Показать сообщение отдельно
  #4 (permalink)  
Старый 26.01.2010, 16:26
Аватар для Shaci
:-/
Отправить личное сообщение для Shaci Посмотреть профиль Найти все сообщения от Shaci
 
Регистрация: 28.09.2009
Сообщений: 1,126

Позволю себе немного пофлудить,
в механизме наследования вроде разобрался:
вот пара примерчиков

//Пример, вариант 1:
function A() {};
function B() {};
function C() {};

B.prototype = new C();
alert(B.prototype.__proto__.constructor == C);//true
//B.prototype.__proto__.constructor (да) --> C
alert(B.prototype.__proto__.__proto__.constructor == Object);//true
//у класса C, C.prototype = new Object()(но с определенным свойством constructor, т.е. {constructor:C;},
//C.prototype.__proto__ = Object.prototype
//C.prototype.constructor = (установлено явно и автоматически при создании) C, C.prototype.__proto__.constructor = Object
//т.е. у "Пустого" прототипа явно устанавливается свойство constructor = C,
//иначе происходило бы наследование этого свойства от прототипа прототипа,
//у прототипа прототипа - так же явно - свойство конструктора Object

alert(B.prototype.constructor == C);//true
//B.prototype.constructor (нет) -->
//B.prototype.__proto__.constructor (да) --> C

alert((new B()).constructor == C);//true
//(new B()).constructor (нет) -->
//B.prototype.constructor (нет) -->
//B.prototype.__proto__.constructor (да) --> C

//Далее
A.prototype = new B();
alert(A.prototype.constructor == C);//true
//A.prototype.constructor (нет) -->
//B.prototype.constructor (нет) -->
//B.prototype.__proto__.constructor (да) --> C
//и.т.д
alert((new A()).constructor == C);//true
//A.constructor --> (нет)
//A.prototype.constructor (нет) -->
//B.prototype.constructor (нет) -->
//B.prototype.__proto__.constructor (да) --> C

//B.prototype.__proto__.constructor = C.prototype.constructor, это понятно


//А вот здесь возникал вопрос, но вроде я на него правильно ответил
//Вариант 2:
function A() {};
function B() {};
function C() {};
var xxx = new B();
A.prototype = xxx;
alert(A.prototype.constructor == B.prototype.constructor);//true, здесь все понятно
alert((new A()).constructor == B.prototype.constructor)//true, ну и далее, сколько угодно вариаций

B.prototype = new C();
alert(C.prototype.constructor == C);//true - понятно
alert(B.prototype.constructor == C);//true - понятно,
alert((new B).constructor == C);//true - понятно

//Вопрос вот здесь возникал:
alert(A.prototype.constructor == C);//false ??????????????????, разве не должен быть true?, ведь мы вроде поменяли свойство constructor у объекта класса B
alert(A.prototype.constructor == B);//true :( !!!
//получается, что прототипом класса A является объектб  который уже существует со своими определенными
//свойствами, и дальнейшие изменения функции конструктора его не касаются, вроде так?
alert(xxx.__proto__.constructor == B);//true!!!!!!
//a не alert(xxx.__proto__.constructor == C); //true
//Т.е. у этого объекта остается старый прототип!!!
//=> у всех объектов класса A будет старый прототип
/*
Из статьи:
Однако, изменение свойства .prototype в конструкторе,
никак не влияет на прототип уже порождённых объектов.
Меняется только (и именно) свойство .prototype конструктора.
Это означает, что новые порождаемые объекты, будут иметь новый прототип.
Порождённые же уже (до смены свойства .prototype) объекты,
имеют связь со своим старым прототипом, и эта связь уже неизменна:
 */



Собственно, похоже, что наткнулся как раз на 2 этих "подводных камня":
из http://javascript.ru/blog/Dmitry-A.-...-OOP.#prototip
1.
Часто в данном моменте бывает путаница - свойство .constructor неверно считают родным свойством порождённого объекта; как видим (в алгоритме создания функций), данное свойство является свойством прототипа, и доступно объекту посредством делегирования.

И
2.
С прототипом объекта также иногда бывает путаница - в качестве него могут неверно считать явную ссылку конструктора - .prototype. Да, действительно, эта ссылка указывает на тот же объект, что и свойство [[Prototype]] объекта:
a.[[Prototype]] ----> Прототип <---- A.prototype

Более того, как мы видели в алгоритме создания объектов, [[Prototype]] черпает информацию из .prototype. Однако, изменение свойства .prototype в конструкторе, никак не влияет на прототип уже порождённых объектов. Меняется только (и именно) свойство .prototype конструктора. Это означает, что новые порождаемые объекты, будут иметь новый прототип. Порождённые же уже (до смены свойства .prototype) объекты, имеют связь со своим старым прототипом, и эта связь уже неизменна

Вроде так.
Ответить с цитированием