一起养成写作习惯!这是我参与「掘金日新计划 · 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
参考资料
- 浅谈 instanceof 和 typeof 的实现原理:juejin.cn/post/684490…
- MDN-instanceof:developer.mozilla.org/zh-CN/docs/…
- MDN-typeof:developer.mozilla.org/zh-CN/docs/…
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。