почему перечисление фактического конструктора класса в javascript важно
Я читал на javascript garden http://bonsaiden.github.com/JavaScript-Garden/ о прототипе в javascript и один из его примеров выглядит так:
function Foo() {
this.value = 42;
}
Foo.prototype = {
method: function() {}
};
function Bar() {}
// Set Bar's prototype to a new instance of Foo
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';
// Make sure to list Bar as the actual constructor <-------------------
Bar.prototype.constructor = Bar;
Обратите внимание на строку, которая читает Make sure to list Bar как фактический конструктор. Я действительно теряюсь в том, что это делает/есть. Я попытался создать новые экземпляры Bar() с последней строкой и без нее. Но вызов " value "или" method " в этих экземплярах возвращает те же самые вещи. Поэтому я задаюсь вопросом, зачем это нужно (я предполагаю должно быть одно) указание конструктора?
Спасибо!!!
2 ответа:
Каждая функция имеет свойство
prototype
, оно присваивается при создании объекта функции, оно указывает на вновь созданный объект, который наследуется отObject.prototype
, и оно имеет свойствоconstructor
, которое просто указывает на саму функцию.Назначение свойства
prototype
- дать способ реализации наследования, используя функции конструктора. Когда вы вызываете функцию с операторомnew
, она создает новый объект, который наследуется от этого конструктораprototype
.Теперь, назначение свойства
constructor
состоит в том, чтобы иметь возможность ссылаться на конструктор, создавший объект, например:function Foo () {} // default value of the property: Foo.prototype.constructor == Foo; // true
Это свойство наследуется "экземплярами"
Foo
, поэтому вы можете знать, какой конструктор использовался для создания объекта:var foo = new Foo(); foo.constructor == Foo;
Если вы назначаете новый объект прототипу функции, эта связь теряется:
function Bar () {} Bar.prototype = { inherited: 1 }; Bar.prototype.constructor == Bar; // false Bar.prototype.constructor == Object; // true
И это влияет также на экземпляры функции:
var bar = new Bar(); bar.constructor == Bar; // false bar.constructor == Object; // true
Другой подобный случай, когда у вас есть два или более уровней наследования с помощью конструкторов, наиболее распространенным способом, используемым для обозначения отношения наследования между функциями, является присвоение свойства
prototype
второго уровня, например:В приведенном выше коде есть несколько проблем, во-первых, он выполняет логику родительского конструктора для создания отношения наследования, но это уже другая история, в приведенном выше примере также затрагивается СВОЙСТВОfunction Parent() {} function Child () {} Child.prototype = new Parent();
constructor
, так как мы полностью заменяемChild.prototype
объект:var child = new Child(); child.constructor == Parent; // true
Если мы заменим значение свойства
constructor
Child.prototype
после его присвоения, оно покажет ожидаемое поведение:function Child() {} Child.prototype = new Parent(); Child.prototype.constructor = Child; var child = new Child(); child.constructor == Child; // true
Я полагаю, что это связано с созданием экземпляра Bar с новым ключевым словом. Я считаю, что использование нового будет искать бар.прототип.конструктор. Перед этой линией объект, связанный с баром.прототип.contructor имеет тип Foo, поэтому при создании экземпляра без этой строки он будет создавать объект Foo вместо объекта Bar.