深入理解JavaScript-instanceof——找祖籍

简介: 我们分别在 JavaScript由什么组成 和 JavaScript 中的始皇 两篇文章中讲到了 instanceof,这篇文章好好说说 instanceof

什么是 instanceof?


MAN 的解释是:


instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上


由此可知,instanceof 的左侧必须是对象,才能找到它的原型链

而 instanceof 右侧必须是函数,函数才会有 prototype 属性

简单例子:


function Resume(name, age, hobby) {
    this.name = name;
    this.age = age;
    this.hobby = hobby;
}
const johan = new Resume('johan', '18', 'swim');
console.log(johan instanceof Resume); // true
console.log(johan instanceof Object); // true


JavaScript 中的始皇 中有个例子:

Object instanceof Object
Function instanceof Function


我们可以这样理解,Object 的某一原型链上有一值和 Object.prototype 相等;Function 的原型链上的某一值也与 Function.prototye 一致;

Object instanceof Object 可以理解为:

  • Object.__proto__ === Function.prototype
  • Function.prototype.__proto__ === Object.prototype
  • Object.__proto__.__proto__ === Object.prototype

Function instanceof Function 可以理解为:

  • Function.__proto__ === Function.prototype

其本质是因为内置函数都是由 Function 构造函数创造的,包括它自己


手写 instanceof


按照以上描述,即左边的__proto__=== 右边.prototype


第一版

// 第一版
function myInstanceof(left, right) {
    if (left.__proto__ === right.prototype) {
        return true;
    } else {
        return false;
    }
}
console.log(myInstanceof(johan, Resume)); // true
console.log(myInstanceof(johan, Object)); // false


第一版我们实现了 左边的__proto__=== 右边.prototype。但这还不够,myInstanceof 还要检测 left 是否在 right 的原型链上。所以我们要递归 left.__proto__ 。直到原型链的最深一层 null


第二版


// 第二版
function myInstanceof(left, right) {
    if (left.__proto__ === right.prototype) {
        return true;
    } else {
        if (left === null) {
            return false;
        }
        return myInstanceof(left.__proto__, right);
    }
}


第三版:考虑它是基本类型


在一开始就说了,instanceof 的左侧必须是对象,这样才能找到它的原型链

但不要忘记了,除了 null、undefined 外的基本类型,都是由基本包装类型“保护”着


var num = 1;
console.log(myInstanceof(num, Number)); // true
console.log(num instanceof Number); // false


所以我们要增加对基本类型的判断

function myInstanceof(left, right) {
    if (typeof left !== 'object' || left === null) return false;
    if (left.__proto__ === right.prototype) {
        return true;
    } else {
        if (left === null || left.__proto__ === null) {
            return false;
        }
        return myInstanceof(left.__proto__, right);
    }
}


看看别人的 instanceof 实现


function myInstanceof(left, right) {
    // 基本数据类型直接返回 false
    if (typeof left !== 'object' || left === null) return false;
    // getPrototype是Object对象自带的一个方法,等效于__proto__
    let proto = Object.getPrototypeOf(left);
    while (true) {
        // 循环往下寻找,知道找到相同的对象
        if (proto == null) return false;
        // 找到相同的原型对象
        if (proto == right.prototype) return true;
        proto = Object.getPrototypeOf(proto);
    }
}

while 的用法比俺高级多了

相关文章
|
3月前
|
JavaScript 前端开发
深入理解JavaScript中的原型链
本文将深入探讨JavaScript中的原型链机制,从根本上理解它的工作原理以及在开发中的应用。我们将介绍原型链的概念、如何创建和使用原型、原型链的继承机制以及一些常见的原型链相关问题。通过对原型链的详细解析,读者将能够更好地理解JavaScript中的继承、原型对象和原型链之间的关系,提高代码的质量和可维护性。
|
3月前
|
JavaScript 前端开发 开发者
深入理解JavaScript对象创建
深入理解JavaScript对象创建
|
3月前
|
前端开发 JavaScript
前端深入理解JavaScript面向对象编程与Class
随着JavaScript的发展,ECMAScript 6(ES6)引入了许多新的语言特性和语法糖,其中包括了面向对象编程的Class(类)机制。Class提供了一种更简洁、更直观的方式来定义对象和操作对象的行为。本文将介绍ES6中Class的概念、语法和特性,并通过示例代码来说明其实际应用。
|
JavaScript 前端开发
深入理解JavaScript- Object(对象)
深入理解JavaScript- Object(对象)
105 0
深入理解JavaScript- Object(对象)
|
存储 自然语言处理 JavaScript
深入理解JavaScript-Function
深入理解JavaScript-Function
94 0
深入理解JavaScript-Function
|
JSON JavaScript 前端开发
深入理解JavaScript-一切皆对象
深入理解JavaScript-一切皆对象
180 0
深入理解JavaScript-一切皆对象
|
设计模式 JavaScript 前端开发
深入理解JavaScript-继承
深入理解JavaScript-继承
73 0
深入理解JavaScript-继承
|
JavaScript 前端开发 算法
深入理解JavaScript——数组
我们在前文系列中,我们以内置构造函数 Object 开始讲起,并从中衍生出各种知识点。而后我们又讲另一个大构造函数 Function,同样引出了比肩 Object 的知识点。这两者之后,笔者认为JavaScript的大厦已经建成,只是天边还有两朵小乌云,今天我们就讲其中的一朵——数组
118 0
深入理解JavaScript——数组
|
JavaScript 前端开发 API
深入理解JavaScript- new 做了什么
上文我们就 Object 进行分析阐述,聊到了对象的创建,其中 new 是创建对象的重要关键字,这节我们讲讲 new,聊一聊 new 是做什么用的
161 0
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript-this关键字
深入理解JavaScript-this关键字
60 0