Каждая функция имеет свойство 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