x .__ proto__ == X.prototype与javascript中的x instanceof X并不总是相同?

sou*_*ics 2 javascript prototypal-inheritance node.js

我知道不应该__proto__直接在代码中使用,但出于好奇,我在节点中玩这个.我的印象是,如果x.__proto__ == X.prototype那时它意味着x instanceof X会产生,true直到我用原始值命中这个代码.

> (2).__proto__ ==  Number.prototype
true
> 2 instanceof Number
false
> (2) instanceof Number
false


> "abc".__proto__ == String.prototype
true
> "abc" instanceof String
false
> ("abc") instanceof String
false
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

T.J*_*der 6

instanceoffalse如果左侧不是对象,则总是会产生(参见此处的步骤3).

原因(2).__proto__ == Number.prototype是当您将属性访问器应用于基元(在本例中.__proto__)时,会创建并使用具有相同基础基元值的临时对象.

所以你__proto__从属性中得到的东西与你在instanceof案例中使用的东西不同,因为它不是原始的.您的测试用例更准确地是:

> (2).__proto__ == Number.prototype
true
> new Number(2) instanceof Number
true

我的印象是,如果x.__proto__ == X.prototype那时它意味着x instanceof X会产生true

这是正确的(或者如果你使用的话===,这是一个相当模糊的原因1),但请注意反过来不是真的:如果x instanceof X是真的,那并不一定意味着x.__proto__ == X.prototype是真的,对于一对原因:

  1. 这可能是因为你需要使用x.__proto__.__proto__,或x.__proto__.__proto__.__proto__,或... :-)

  2. x.__proto__可能是undefined.例如,如果你这样创建x:x = Object.create(null).原因是__proto__属性访问器是由提供者提供的Object.prototype,但如果您创建了一个不从中继承的对象,则Object.prototype它没有__proto__属性访问器(在兼容的实现上).这是使用的一个原因Object.getPrototypeOf(x).


1个相当模糊的原因:如果x是通过创建Object.create(null)(或使用不追溯任何的原型Object.prototype),因此不具有__proto__属性访问器,并且X.prototypenull,x.__proto__ == X.prototypetrue即使他们很可能是完全彻底无关,因为x.__proto__会是的undefined,undefined == null是真的.;-)