instanceof 原理

136 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

核心描述

  • 定义:instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
  • 原理
    • 实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可
    • 代码示例:
    function new_instance_of(leftVaule, rightVaule) { 
        let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
        leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
        while (true) {
        	if (leftVaule === null) {
                return false;	
            }
            if (leftVaule === rightProto) {
                return true;	
            } 
            leftVaule = leftVaule.__proto__ 
        }
    }
    
    
  • 注意事项:
    • 如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 obj 和 Foo.prototype 的值都有可能会改变
    • Object.create(null) instanceof Object 为 false

知识拓展

  • typeof 的说明
    • 作用:typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
    • 原理:在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。
    • 注意事项:
      • typeof null 会返回 "object",因为最开始 JS 底层的对象和 null 都用0表示
      • typeof /s/ 在不同的浏览器版中返回的不同,有返回 function 的,也有返回 object 的,与低版本浏览器实现有关,正常应该返回 object
      • typeof document.all === 'undefined';尽管规范允许为非标准的外来对象自定义类型标签,但它要求这些类型标签与已有的不同。document.all 的类型标签为 'undefined' 的例子在 Web 领域中被归类为对原 ECMA JavaScript 标准的“故意侵犯”。
      • let、const:但在加入了块级作用域的 let 和 const 之后,在其被声明之前对块中的 let 和 const 变量使用 typeof 会抛出一个 ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。
      • 除 Function 外的所有构造函数的类型都是 'object'
  • 最优的判断对象类型的方法:
Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
  • 小结:
    • 想要判断一个对象的具体类型可以考虑用 instanceof,但是 instanceof 也可能判断不准确,比如一个数组,他可以被 instanceof 判断为 Object
    • 想要判断一个基础数据类型,可以考虑用 typeof ,但是要注意 typeof 也有不准的情况,如 null

参考资料

浏览知识共享许可协议

本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。