深入理解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 的用法比俺高级多了

相关文章
|
双11
29 岁成为阿里巴巴P8,工作前5年完成晋升3连跳,他如何做到?
泡泡是我的好朋友。今年31岁,毕业后就进了阿里巴巴,工作五年内从P4晋升至 P6、P7、P8。
5331 0
|
5月前
|
安全 Linux API
Burp Suite Professional 2025.4 发布 - Web 应用安全、测试和扫描
Burp Suite Professional 2025.4 (macOS, Linux, Windows) - Web 应用安全、测试和扫描
273 6
Burp Suite Professional 2025.4 发布 - Web 应用安全、测试和扫描
|
6月前
|
数据可视化 数据挖掘 BI
基于烟草零售商订单数据的Quick BI体验报告
Quick BI旨在通过智能的数据分析和可视化能力帮助企业构建高效的分析系统。在我初步了解该产品后,发现它不仅支持创建美观的仪表板、复杂的电子表格以及动态大屏,还能够无缝集成到现有的业务流程中,极大地提升了工作效率。尤其对于需要频繁展示数据分析结果给管理层或客户的场景来说,Quick BI提供了一个便捷且专业的解决方案。
|
前端开发 JavaScript
使用 JavaScript 实现图片预览功能
使用 JavaScript 实现图片预览功能
319 0
|
10月前
|
存储 SQL 数据处理
数据库设计与管理的要点
在数据库设计和管理过程中,清晰的权限控制、数据处理逻辑、以及高效的查询优化,都是不可或缺的组成部分。
161 2
|
监控 Java 数据挖掘
用Java代码打造游戏反作弊系统
用Java代码打造游戏反作弊系统
396 0
|
存储 数据可视化 大数据
基于Python Django的大数据招聘数据分析系统,包括数据大屏和后台管理
本文介绍了一个基于Python Django框架开发的大数据招聘数据分析系统,该系统具备后台管理功能和数据大屏展示,利用大数据技术收集和分析招聘市场趋势,帮助企业和招聘机构提高招聘效率和质量。
393 3
|
机器学习/深度学习 人工智能 算法
用Python实现简单的聊天机器人
【8月更文挑战第31天】 本文将介绍如何使用Python语言和AIML库来实现一个简单的聊天机器人。我们将从基本的安装和配置开始,然后逐步深入到聊天机器人的实现过程。最后,我们将展示如何训练我们的机器人以使其更加智能。无论你是编程新手还是有经验的开发者,都可以从本文中获得实用的知识。
|
前端开发 Java 数据库连接
技术好文共享:电脑睡眠(sleep)和休眠(Hibernate)的区别,以及休眠功能的设置
技术好文共享:电脑睡眠(sleep)和休眠(Hibernate)的区别,以及休眠功能的设置
|
XML 分布式计算 资源调度
Hadoop本地运行模式(Grep案例和WordCount 案例)
Hadoop本地运行模式(Grep案例和WordCount 案例)
520 1