Показать сообщение отдельно
  #2 (permalink)  
Старый 20.01.2010, 14:38
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Shaci
//Далее назначим явно прототип
MyArray1.prototype = new MyArray2();
MyArray1.prototype - теперь "пустой" объект (порождённый от MyArray2), не имеющий свойства constructor.

Сообщение от Shaci
//Так как теперь прототип указан "явно", то, по умолчанию, его свойство constructor равно его
   //коструктору
   alert("(MyArray1.prototype.constructor == MyArray2) = " + (MyArray1.prototype.constructor == MyArray2));//true
   //и, соответственно
   alert("(MyArray1.prototype.constructor == MyArray1) = " + (MyArray1.prototype.constructor == MyArray1));//false
У MyArray1.prototype, собственного свойства constructor, как мы отметили выше, нет, так? Соответственно, оно откуда-то наследуется (раз равенство на MyArray2 даёт true).

В общем случае схема очень простая:

1. При обращении к свойству объекта, если оно не найдено в самом объекте, его поиск продолжается в прототипе объекта; далее, если не найдено, в прототипе прототипа и т.д. - т.е. в цепи прототипов;

2. Самый важный момент - прототип объекта - это внутреннее (недоступное напрямую) свойство [[Prototype]]. Свойство же .prototype из конструктора объекта - это ссылка на прототип, из которой будет установлен [[Prototype]] объекта при создании объекта. Сам же объект (после того, как был создан) держит связь со своим прототипом через это свойство [[Prototype]].

Поэтому цепь прототипов - это:

object.[[Prototype]].[[Prototype]].[[Prototype]].и т.д., пока не будет null


Возвращаясь к MyArray1.prototype,

MyArray1.prototype порождён от конструктора MyArray2 и является обычным объектом; прототип MyArray1.prototype установлен из MyArray2.prototype:

MyArray1.prototype.[[Prototype]] === MyArray2.prototype


Соответственно, при обращении к MyArray1.prototype.constructor, свойство constructor будет найдено по цепи:
MyArray1.prototype.constructor --> не найдено;
MyArray1.prototype.[[Prototype]].constructor --> найдено и == MyArray2


Равенство MyArray1.prototype.constructor == MyArray1 будет давать, правильно, false, опять же, из-за особенности цепи прототипов. Чтобы исправить это, свойство constructor, после смены свойства .prototype в конструкторе, выставляют вручную:

MyArray1.prototype = new MyArray2();
MyArray1.prototype.constructor = MyArray1;


Сообщение от Shaci
//теперь наследование свойства constructor, происходит , видимо, несколько не так, как
   //наследование обычного свойства:
   alert("(second.constructor == MyArray1) = " + (second.constructor == MyArray1));//false
   alert("(second.constructor == MyArray2) = " + (second.constructor == MyArray2));//true - наследуется свойство constructor прототипа
   //хотя по идее, если не ошибаюсь, должно происходить перекрытие свойств родителя
После смены свойства constructor вручную, должно быть правильно:

second.constructor == MyArray1; // true
second.constructor == MyArray2; // false


Опять же, свойство constructor в объекте second найдено по цепи:

second.constructor --> нет
second.[[Prototype]].constructor --> (мы выставили его вручную) да === MyArray1

Если бы не выставили, было бы:

second.constructor --> нет
second.[[Prototype]].constructor --> нет
second.[[Prototype]].[[Prototype]].constructor --> да === MyArray2


Подробней про прототип: http://javascript.ru/blog/Dmitry-A.-...-OOP.#prototip

Сообщение от Shaci
alert("(MyArray1.prototype.constructor == MyArray2) = " + (MyArray1.prototype.constructor == MyArray2));// ??? true, а здесь не
   //должно происходить какое-нибудь очередное наследование конструктора прототипа?,
   //он же объект класса MyArray2 и имеет прототип - объект класса Array => его конструктор
   //по идее должен наследоваться?
   //т.е. MyArray1.prototype.constructor по идее должен быть равен Array???? или нет..
Как уже было сказано, прототип объекта (внутреннее свойство [[Prototype]]) устанавливается при создании объекта и дальше изменён (полностью на новый объект) быть не может. Поэтому MyArray1.prototype.[[Prototype]] установился в MyArray2.prototype при создании через new MyArray2().

Прочитайте статью про ООП полностью: http://javascript.ru/blog/Dmitry-A.-...-CHast-7.-OOP.

Успехов!
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 20.01.2010 в 14:45.
Ответить с цитированием