Да.. ошибки в книжке создателя jQuery. Ладно там опечатки в именах переменных, но нет целой строчки. Или ее просто не заметили. Надо бы ему написать. Хотя сколько лет прошло, книжка 2006 года :)
Книжка: Pro JavaScript Techniques, Apress, Copyright © 2006 by John Resig
В тестовой программе написанной для разбора этого фрагмента кода, я создал цепь из 3х объектов
где последующий наследует предыдущий. И каждый из этих объектов вызывал функцию doo, которая
вызывала одноименную функцию родительского объекта (через this.uber('doo')).
И все это работало, хотя с пропущенной строчкой должно было спотыкаться на
v = v.constructor.prototype; Хотя, оно и спотыкается только при 3 звеньях цепи это не заметно.
Браузер интерпретировал constructor всех объектов равный первому
конструктору базового объекта в цепи. И цикл for сразу втыкал нас в базовый объект всего наследования.
Когда цепочка только из трех объектов ошибки не видно.
у нас v - всегда утыкается в крайний объект. Но этот крайний объект и есть цель единственной итерации цикла for. В итоге все работает.
Когда цепочка более чем из трех обектов - у нас v = v.constructor.prototype - сразу утыкается в крайний объект, и это заметно, так как базовый объект не является целью цикла for, требуется остановиться на объекте где то по середине цепочки. Итог цикл становиться бесполезен. Все ломается.
При трех объектах в цепи не заметно.
При 4 и более - ошибка.
Listing 3-2. Douglas Crockford’s Three Functions for Simulating Classical-Style Inheritance Using (исправленно)
------------------------------------------
Function.prototype.method = function(name,funct){
this.prototype[name] = funct;
return this;
}
Function.method('inherits',function(parent){
var proto = this.prototype = new parent();
proto.constructor = parent; // only OBJ can have constructor
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ how this line could be omit
// at the John Resig book? that's why everything dose not work
//this.constructor = parent;
var depth = 0;
this.method('uber',function(name){
var v = parent.prototype;
var ret;
var funct;
if(0!=depth){
for(var i=0; iv = v.constructor.prototype;
}
funct = v[name];
}else{
funct = proto[name];
if(funct == this[name]){
funct = v[name];
}
}
depth++;
ret = funct.apply(this,Array.prototype.slice.apply(arguments,[1]));
depth--;
return ret;
});
return this;
});