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

x.__proto__ == X.prototype is not always same as x instanceof X in javascript?

我知道不应该在代码中直接使用 __proto__,但出于好奇我在 node.js 中尝试了这个。我的印象是如果 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

这是为什么?

如果左侧不是对象,

instanceof 将始终产生 false(参见 Step 3 here)。

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

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

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

I was under the impression that if x.__proto__ == X.prototype then it means x instanceof X will yield true

就目前情况而言,这是正确的(或者如果您使用 ===,出于相当模糊的原因 1),但请注意,相反的情况并非如此true:如果 x instanceof X 为真,那并不一定意味着 x.__proto__ == X.prototype 为真,原因如下:

  1. 您可能需要使用 x.__proto__.__proto__,或 x.__proto__.__proto__.__proto__,或...:-)

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


1 相当晦涩的原因:如果 x 是通过 Object.create(null) 创建的(或使用任何无法追溯到 [=29= 的原型) ]),因此没有 __proto__ 属性 访问器,而 X.prototypenullx.__proto__ == X.prototype 将是 true,即使它们可以我们完全没有关系,因为 x.__proto__ 将是 undefinedundefined == null 是真的。 ;-)

原始值不是对象,因此不是任何构造函数的实例。

如果您将值强制转换为对象,您的检查将起作用:

console.log(Object(2) instanceof Number); // true
console.log(Object("abc") instanceof String); // true
console.log(Object(true) instanceof Boolean); // true
console.log(Object(Symbol()) instanceof Symbol); // true