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

时间:2016-12-18 15:36:31

标签: javascript node.js prototypal-inheritance

我知道不应该在代码中直接使用__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

为什么会这样?

2 个答案:

答案 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将是真的,原因有两个:

  1. 您可能需要使用x.__proto__ == X.prototypex.__proto__.__proto__或......: - )

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

  3. 1 相当模糊的原因:如果Object.getPrototypeOf(x)是通过x创建的(或使用任何不追溯到Object.create(null)的原型),那么没有Object.prototype属性访问者,而__proto__X.prototypenull将为x.__proto__ == X.prototype,即使它们可能完全无关,因为{ {1}}为truex.__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