Свойства, объявленные * в * конструкторе, видны в экземплярах. Зачем? - PullRequest
1 голос
/ 17 января 2011

В системе наследования прототипов Javascript внутренняя ссылка на прототип объекта устанавливается в свойстве «prototype» его конструктора, которое само является объектом.

Свойства свойства «prototype» конструктора могут быть разрешены, как если бы они были свойствами экземпляров объекта. Однако фактические свойства объекта конструктора не доступны для экземпляра:

function MyConstructor() { }
MyConstructor.x = 3
MyConstructor.prototype.y = 7

a = new MyConstructor()
a.x == 3    // FALSE
a.y == 7    // TRUE

Однако, если свойство («x») конструктора объявлено в теле функции с ключевым словом this, эти свойства , конечно, разрешаются экземплярами:

function MyConstructor() {
    this.x = 3
}
MyConstructor.prototype.y = 7

a = new MyConstructor()
a.x == 3    // TRUE

Почему? В чем разница?

1 Ответ

6 голосов
/ 17 января 2011

Когда вы делаете это:

MyConstructor.x = 3;

... вы только добавили свойство к экземпляру объекта Function, на которое ссылается MyConstructor. У объекта Function есть много свойств, которые не становятся частью экземпляра (и вы не захотите их).

Таким образом, механизм создания свойств экземпляра с помощью конструктора заключается в использовании метода this.x.

Когда конструктор работает, this равен возвращаемому объекту. Так что это просто удобство, поэтому вам не нужно делать:

a = new MyConstructor();
a.x = 3;
a.x == 3    // TRUE!

Поскольку this в конструкторе совпадает с результирующим объектом, нет необходимости делать это явно при каждом создании нового экземпляра.

Объект prototype - это просто объект, на который ссылаются все экземпляры MyConstructor, поэтому, если у экземпляра нет свойства, он затем идет к prototype, чтобы найти его.


Чтобы проиллюстрировать связь между this и новым экземпляром, рассмотрим следующий пример:

Пример: http://jsfiddle.net/M2prR/

var test; // will hold a reference to "this"

function MyConstructor() {
    test = this; // make "test" reference "this"
}

   // create a new instance
var inst = new MyConstructor;

   // see if they are the same object. This will alert "true"
alert( inst === test );
...