2

У меня есть следующий код JavaScriptпроверка InstanceOf работает на подклассу без установки конструктора

function Parent() { 
} 

function Child() { 
} 

Child.prototype = Object.create(Parent.prototype); 

Обратите внимание на отсутствие заявления

Child.prototype.constructor = Child; 

Я понимаю, что как constructor свойство не было установить instanceof проверки должны завершиться неудачно для новых экземпляров класса Child.

var child = new Child(); 
child instanceof Child; //Should give false 

Я проверил, что конструктор неправильно установлен enter image description here

Но когда я бегу child instanceof Child он дал мне истинное

enter image description here

Но это должно быть false, как конструктор свойство не установлено на прототипе Child будет Child.

Environment

Google Chrome Version 48.0.2564.109 (64-bit) 
Ubuntu 14.04 LTS 
+0

Связанный: http://stackoverflow.com/questions/8453887/why-is-it-necessary-to-set-the-prototype-constructor –

+0

@Bergi Хотя ответ на этот вопрос может быть связан с этим вопросом, ИМО вопросы разные. –

+0

@AseemBansal: определение SO «дубликат» (возможно, удивительно) не о том, что * вопросы * одинаковы, но отвечает ли ответ * на более ранний вопрос на этот вопрос. (Это также не уничижительно, а дубликаты улучшают шансы найти ответ, формулируя вопросы по-разному.) Я думаю, что Берги прав. (Он хорош в дубликатах.) –

ответ

4

Я понимаю, что, как свойство конструктора не было установлено проверка InstanceOf должна терпеть неудачу для новых экземпляров класса Child.

Нет, это неправильно. Фактически, до ES2015 (aka ES6), свойство constructor не было использовано для чего-либо вообще в самом JavaScript. Это было определено как существующее на объектах по умолчанию, время выполнения присваивает свойству prototype функции, но не .

instanceof все равно construtor. Рассмотрим:

o instanceof Foo 

instanceof будет выглядеть, чтобы увидеть, если объект Foo.prototype указывает на это в любом месте на цепочке прототипов o «s. (Если «цепочка прототипов» не является знакомым термином, см. * В конце ответа, а затем возвращайтесь.) Если это так, он возвращает true; если нет, он возвращает false.

Например, вот концептуальный implementaton из instanceof, ручной отмахиваясь некоторые детали:

function isAnInstance(obj, func) { 
    var p; 
    for (p = Object.getPrototypeOf(obj); p; p = Object.getPrototypeOf(p)) { 
     if (p === func.prototype) { 
      return true; 
     } 
    } 
    return false; 
} 

Хотя это вытесняется в ES2015 спецификации, я ссылку на спецификацию ES5, потому что она написана в более доступной язык и этот аспект не изменился: instanceof эффективно просто вызывает внутренний метод функции [[HasInstance]], defined here.

Мы можем видеть, что constructor не участвует из вашего вопроса, а также от этой простой демонстрации:

var p = {}; 
 
var o = Object.create(p); 
 
var Foo = function() {}; 
 
Foo.prototype = p; 
 
snippet.log(o instanceof Foo); // true
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Заметим, что:

  1. o не было созданный через Foo
  2. На самом деле, Foo даже не существовать пока o была создана
  3. o и его прототип не имеют constructor собственности на всех

... и еще instanceof говорит: «Да, внешность как будто это Foo. " :-) Чисто, потому что объект Foo.prototype указывает на также на прототип цепи o.


* "прототип цепь"

Вы четко знаете, что объекты JavaScript имеют прототип, из которых они наследуют свойство. Эти прототипы являются объектами, и поэтому у них есть прототипы. Таким образом, вы получаете «цепочку» прототипов.

Рассмотрим два уровня (возможно, три уровня) иерархии наследования, здесь в ES5:

function Base() { 
} 

function Derived() { 
    Base.call(this); 
} 
Derived.prototype = Object.create(Base.prototype); 
Derived.prototype.constructor = Derived; 

... или в ES2015:

class Base { 
} 
class Derived extends Base { 
} 

Теперь мы используем его:

var d = new Derived(); 

(Где увидеть «d объект»и аналогичные в ниже, я, конечно, имею в виду„объект d относится к“  — но это действительно многословным.)

Теперь прототип d объекта является Derived.prototype. Прототипом Derived.prototype является Base.prototype. Base.prototype - прототип Object.prototype. Object.prototype не имеет прототипа (его внутренний номер [[Prototype]] - null).

Эти объекты являются цепочка прототипов, лежащий в основе d, и они имеют в виду, что это dinstanceof Object, instanceof Base и instanceof Derived.

+0

Не могли бы вы перефразировать это - «с объектом, что свойство прототипа функции, которую вы использовали»? Я не могу понять его смысла. Возможно, простой пример? –

+1

@AseemBansal: Знаете, я написал это предложение и подумал: «Хммм, ясно, как грязь?» Посмотрим, смогу ли я это исправить. :-) –

+0

Подождите, где ES6 использует свойство '.constructor' для чего-нибудь? – Bergi

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