2016-12-18 3 views
2

Я знаю, что не нужно использовать __proto__ непосредственно в коде, но просто из любопытства я играл с этим в узле. У меня создалось впечатление, что если x.__proto__ == X.prototype, то это означает, что x instanceof X даст true, пока я не нахожу этот код с примитивными значениями.x .__ proto__ == X.prototype не всегда такой же, как x instanceof X в javascript?

> (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 

Почему это?

ответ

6

instanceof всегда будет давать false, если левая сторона не является объектом (см. Step 3 here).

Причина, по которой (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

Это правда, насколько это идет (или если вы использовали ===, по довольно неясной причине), но обратите внимание, что обратное неверно: если 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).


довольно неясная причина: Если x было создано с помощью Object.create(null) (или с помощью любого прототипа, который не трассировать назад к Object.prototype) и, таким образом, не имеет __proto__ свойство аксессора и X.prototypenull, x.__proto__ == X.prototype будет true, хотя они вполне могут быть полностью и совершенно не связаны, поскольку x.__proto__ будет undefined и undefined == null - это правда. ;-)

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

Смежные вопросы