我知道不应该在代码中直接使用__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
为什么会这样?
答案 0 :(得分:6)
instanceof
将始终产生false
。(请参阅Step 3 here)。
(2).__proto__ == Number.prototype
为真的原因是当您将属性访问器应用于基元(在本例中为.__proto__
)时,会创建并使用具有相同基础原始值的临时对象。 / p>
因此,您获取__proto__
属性的内容与您在instanceof
案例中使用的内容不同,因为它不是原始内容。您的测试用例更准确:
> (2).__proto__ == Number.prototype true > new Number(2) instanceof Number true
我的印象是,如果
x.__proto__ == X.prototype
则表示x instanceof X
会产生true
就目前而言(或者如果你使用===
,这是真的,因为一个相当模糊的理由 1 ),但请注意反过来不是这样的:如果{{ 1}}是真的,这并不一定意味着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__
的一个原因。
1 相当模糊的原因:如果Object.getPrototypeOf(x)
是通过x
创建的(或使用任何不追溯到Object.create(null)
的原型),那么没有Object.prototype
属性访问者,而__proto__
为X.prototype
,null
将为x.__proto__ == X.prototype
,即使它们可能完全无关,因为{ {1}}为true
,x.__proto__
为真。 ; - )
答案 1 :(得分:2)
原始值不是对象,因此不是任何构造函数的实例。
如果您将值强制转换为对象,您的检查将起作用:
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