instanceof的疑问

在知乎看到帖子,a instanceof A的意义就是,对a,在其原型链查找(__proto__),如果找到A.prototype,就返回true。下面的代码有点不理解。

Function instanceof Object // true 
 Object instanceof Function // true 
 Function instanceof Function //true
 Object instanceof Object // true
 Number instanceof Number //false

其他测试(也不太理解)

Object.__proto__ === Function.prototype;//true
Function.__proto__ === Function.prototype//true
Function.__proto__ === Object.__proto__;//true
阅读 2.5k
2 个回答

js的类是基于原型链的
我说一下下面三个:

//假设你定义一个A函数:
var A = new Function();

//然后创建了一个A实例(对象)叫a:
var a = new A();
console.log(a instanceof A); //输出为true,A是A类的构造函数,a是A类的一个对象

//因为a和A都有一个原型对象,分别保存在它们不同的属性
console.log(a.__proto__ == A.prototype); 

//同样Object也是一个构造函数,所以我们多了这样声明一个空对象的写法:
var o = new Object(); 

//既然Object是一个函数,那么就是Function的实例:
console.log(Object.__proto__ == Function.prototype); //true
console.log(Object instanceof Function); //true

//同理Function也是一个构造函数,所以有这么写:
//如上面的:var A = new Function(),于是:
console.log(Function.__proto__ == Function.prototype); //true
console.log(Function instanceof Function); //true

//所以:
console.log(Function.__proto__ == Object.__proto__); //true

//另外原型本身是个对象,即Function.prototype是对象:
Function.prototype.__proto__ == Object.prototype; //true

总结一下:

Object.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
Function.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
Number.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype

先理解两者的一个本质区别,prototype 是函数独有的,是人为设定的;__proto__ 是所有对象都有的,是继承的。

然后来看一个两个神的故事:

首先万物起源于一个叫 %ObjectPrototype% 的 intrinsic object,也就是 Object.prototype

接着衍生出第二神,另外一个 intrinsic object %FunctionPrototype%,也就是 Function.prototype。所以

Function.prototype.__proto__ === Object.prototype

Function.prototype 本身也是个函数对象,这是为了兼容 ES5。也估计是让人引起误解的源头。但两者还是不同的,这是个特殊的函数对象,它忽略参数总是返回 undefined,且没有 [[Construct]] 内部方法。

搞清楚了这两个 Ancient Gods 接下来就很容易了,相信也听过“函数在 JS 里是一等公民”这类的说法,其实是因为它们都是 %FunctionPrototype% 的子民(这里不用 Function.prototype 是为了避免混淆,记得 prototype 是人为设定的),包括 Function 本身。

所以你可以看到,Object、Function、String、Number、Boolean 等等等的 proto 都是 Function.prototype。

所以接下来的问题就更容易了,比如 Object instanceof Object。前面我们知道 Object.__proto__ 是 %FunctionPrototype%,而它的 proto 是万物之源 %ObjectPrototype%,恰好也是 Object.prototype,所以就是 true 啦。其它的也是同理,举一反三。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏