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
为真,原因如下:
您可能需要使用 x.__proto__.__proto__
,或 x.__proto__.__proto__.__proto__
,或...:-)
x.__proto__
很可能是 undefined
。例如,如果您像这样创建 x
:x = Object.create(null)
。原因是 __proto__
属性 访问器是由 Object.prototype
提供的,但是如果你创建一个不继承自 Object.prototype
的对象,它就没有 __proto__
属性 访问器(在兼容的实现上)。这是使用 Object.getPrototypeOf(x)
的原因之一。
1 相当晦涩的原因:如果 x
是通过 Object.create(null)
创建的(或使用任何无法追溯到 [=29= 的原型) ]),因此没有 __proto__
属性 访问器,而 X.prototype
是 null
,x.__proto__ == X.prototype
将是 true
,即使它们可以我们完全没有关系,因为 x.__proto__
将是 undefined
而 undefined == 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
我知道不应该在代码中直接使用 __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 meansx instanceof X
will yieldtrue
就目前情况而言,这是正确的(或者如果您使用 ===
,出于相当模糊的原因 1),但请注意,相反的情况并非如此true:如果 x instanceof X
为真,那并不一定意味着 x.__proto__ == X.prototype
为真,原因如下:
您可能需要使用
x.__proto__.__proto__
,或x.__proto__.__proto__.__proto__
,或...:-)x.__proto__
很可能是undefined
。例如,如果您像这样创建x
:x = Object.create(null)
。原因是__proto__
属性 访问器是由Object.prototype
提供的,但是如果你创建一个不继承自Object.prototype
的对象,它就没有__proto__
属性 访问器(在兼容的实现上)。这是使用Object.getPrototypeOf(x)
的原因之一。
1 相当晦涩的原因:如果 x
是通过 Object.create(null)
创建的(或使用任何无法追溯到 [=29= 的原型) ]),因此没有 __proto__
属性 访问器,而 X.prototype
是 null
,x.__proto__ == X.prototype
将是 true
,即使它们可以我们完全没有关系,因为 x.__proto__
将是 undefined
而 undefined == 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