почему перечисление фактического конструктора класса в JavaScript важно - PullRequest
8 голосов
/ 11 октября 2011

Я читал в 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;

Обратите внимание на строку, которая гласит Убедитесь, что Bar указан как фактическийконструктор.Я действительно заблудился о том, что это делает / является.Я попытался сделать новые экземпляры Bar () с и без последней строки.Но вызов «value» или «method» в тех случаях возвращает те же самые вещи.Итак, мне интересно, зачем нужно (я предполагаю, что он должен быть) указания конструктора?

Спасибо !!!

Ответы [ 2 ]

6 голосов
/ 11 октября 2011

Каждая функция имеет свойство 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
2 голосов
/ 11 октября 2011

Я считаю, что это связано с созданием экземпляра Bar с новым ключевым словом. Я полагаю, что использование new будет искать Bar.prototype.constructor. Перед этой строкой объект, связанный с Bar.prototype.contructor, имеет тип Foo, поэтому при создании экземпляра без этой строки он создает объект Foo вместо объекта Bar.

...