“ 知其然而知其所以然,我们都知道instanceof 用来干嘛,那也应该要知道其实现原理”
01
—
instanceof用途
相信大多数人都用过instanceof 操作符,不扯淡,下面先简单说下基本使用方式和场景。
场景
当大家用到instanceof 的时候,大多数是你的typeof 已经不能满足要求了。typeof 在处理基本数据类型的时候还是没问题的,但是在判断引用类型的变量时,就显得力不从心了。
基本使用
console.log([] instanceof Array);//trueconsole.log([] instanceof Object);//trueconsole.log( ({}) instanceof Object );//trueconsole.log(typeof null);//"object"console.log( null instanceof Object );//false
好,以上给出了instanceof 几个基本的使用方式,大伙看着基本上没毛病,那么问题来了:
-
为什么第1和第2行的结果是相同的?instanceof 到底是怎么实现的?
-
为什么第5行结果判断null是Object ,而第6行instanceof 说 null 又不是Object 类型。
带着这两个问题来看instanceof实现过程。
02
—
模拟instanceof实现原理
通过prototype来判断具体类型,并且通过函数的方式来进行模拟,c++底层是从其他方式来实现的。
// A instanceof B 模式A为left B为rightfunction myInstanceof(left, right){//拿到left实例的__proto__属性(隐式原型)var left_proto_ = left === null ? null : left.__proto__;//拿到right的prototype属性(显式原型)var rightProto = right.prototype;//为什么要while语句???while(true){//兼容 null 的情况if(left_proto_ === null){return false;}//当隐式原型严格等于显式原型if(left_proto_ === rightProto){return true;}//这为什么要重新赋值???left_proto_ = left_proto_.__proto__;}}//测试console.log(myInstanceof([], Array));//trueconsole.log(myInstanceof([], Object));//trueconsole.log(myInstanceof(null, Object));//false
看上面代码,表明了两处可能会让人比较疑惑的地方(第7行和第17行)。
这两行代码的原因主要是为解决上面引入的第一问,就是用来处理[]既是Array类型也是Object类型的情况,通过__proto_查找直到为null。
至于第二问中null 既是对象,而又不是对象类型的问题,其实是JavaScript设计中的一个bug。而站在原型链角度来理解,null 是原型链的顶端,自然用instanceof操作任意类型的变量都应该为false,这一点instanceof的逻辑是没有错的。
以上是个人对instanceof的一些理解,如有瑕疵,请斧正!!!
后续更新文章将第一时间更新在公众号中,欢迎关注!!!

本文探讨了JavaScript中instanceof操作符的使用场景与实现原理,解释了其如何通过原型链判断对象类型,包括对null特殊性的解析。
669

被折叠的 条评论
为什么被折叠?



