Быстрое наследование Javascript: понимание __proto__

Учитывая следующий конструктор,

Dog = function(name, age, ...){
    Animal.call(this, name, age, ...);
    // And some other stuff that dogs do
}

Я использую следующую строку кода, чтобы скопировать свои методы и свойства из класса Animal,

Dog.prototype = new Animal();

Не могли бы вы просветить меня, чем это отличается от

Dog.prototype.__proto__ = Animal.prototype;

так как они, кажется, имеют тот же эффект.


person Dave    schedule 03.06.2011    source источник


Ответы (2)


__proto__ — это нестандартное расширение JavaScript (распространенное в различных интерпретаторах, но нестандартное), которое дает вам прямой доступ к прототипу объекта. Свойство prototype объектов-функций — это объект, который будет назначен в качестве прототипа объекта, созданного путем вызова функции через new. Поэтому, когда вы назначаете prototype.__proto__, вы назначаете прототип объекта, который будет установлен в качестве прототипа для новых объектов, созданных функцией.

Поскольку цепочка прототипов работает так, что свойства прототипа отображаются как унаследованные свойства объекта (и это продолжается в цепочке), если вы назначаете Dog.prototype.__proto__, объекты, созданные Dog, будут иметь доступ к этим свойствам косвенно через цепочку. цепь:

+-----------------+      +----------------+      +-------------------------+
| instance of Dog |----->| Dog.prototype  |----->| Dog.prototype.__proto__ |
|                 |      |                |      | `foo` property          |
|                 |      |                |      | `bar` property          |
+-----------------+      +----------------+      +-------------------------+

Когда вы назначаете непосредственно Dog.prototype, экземпляры имеют более прямую ссылку:

+-----------------+      +----------------+
| instance of Dog |----->| Dog.prototype  |
|                 |      | `foo` property |
|                 |      | `bar` property |
+-----------------+      +----------------+

(Обратите внимание, что приведенное выше слегка вводит в заблуждение, ссылаясь на Dog.prototype таким образом. Экземпляры Dog получат прямую ссылку на объект на Dog.prototype при вызове new Dog; если вы назначите совершенно другой объект для Dog.prototype позже экземпляры, которые уже существуют, будут иметь старый прототип, а новые экземпляры получат новый, но это побочный момент.)

person T.J. Crowder    schedule 03.06.2011
comment
Также стоит отметить, что Dog.prototype.__proto__ скорее всего является либо Object.prototype, либо Function.prototype (в зависимости от объекта, назначенного как Dog.prototype), если только не была создана более обширная цепочка. Таким образом, добавленные к нему свойства могут быть унаследованы всеми функциями или объектами (включая все функции, поскольку они также наследуются от Object.prototype). - person RobG; 03.06.2011
comment
@RobG: Да, хорошая мысль. OP заменял __proto__, а не присваивал ему свойства, но, тем не менее, если бы они вместо этого добавляли к нему свойства, это, вероятно, было бы... уродливым. :-) - person T.J. Crowder; 03.06.2011

__proto__ позволяет получить доступ к внутреннему атрибуту [[Prototype]] объекта. Его можно использовать для получения или установки прототипа уже существующего объекта.

protoype — это свойство функции для установки прототипа объектов, которые будут создаваться этой функцией.

Afaik, только Firefox позволяет вам использовать __proto__. Не является стандартным и устарел .


Стоит прочтения:

person Felix Kling    schedule 03.06.2011
comment
Отлично, спасибо, добавил эти две в стопку открытых вкладок для чтения. :) - person Dave; 03.06.2011