JavaScript Классическое наследование
Этот день настал... Впервые за 2 месяца обучения я вижу код на JavaScript который не понял после тщательного разбора каждой строки, не понял вообще как он работает. Это функции созданные для имитации классического наследования. Что такое классическое наследование я вроде знаю их PhP это когда создатся класс и обьекты созданые этим классом наследуют его свойства и методы.
Вот код, сообщения типо код отстойный надо поправить (хотя вратли так кто-нибудь скажет ведь это код самого Дугласа Крокфорда (сообщение чё эт за тип тоже не писать)) постить не надо. Даже если есть код в 100 раз легче но с таким же результатом мне пофиг. Так как мне надо именно разобратся в этом коду.
//Простой вспомогательный метод, метод позволяющий привязать новую функцию к прототипу обьекта
Function.prototype.method = function(name, func) {
this.prototype[name]=func;
return this;
};
//Довольно сложная функция, позволяющая весьма изящно наследовать функции обьектов и сохранять возможность вызова функции "родительского окнаЭ обьекта
Function.method("inherits", function(parent) {
//Отслеживание, на каком уровне глубины в родительских функциях мы находимся
var depth=0;
var proto = this.parent = new parent();
//Создание новой "привилегированной" функции под названием "uber", которая при вызове выполняет любую функцию вписанную в наследование
this.method("uber", function uber(name) {
var func;//Исполняемая функция
var ret;//Возвращение значения функции
var v = parent.prototype;//родительский прототип
//Если мы уже находимся внутри другой функции "uber"
if(depth){
//Спуск на необходимую глубину для поиска исходного прототипа
for(var i=d; i > 0; i+= 1) {
v = v.constructor.prototype;
}
//И получение функции из прототипа
func=v[name];
//А если это первый вызов "uber"
} else {
//Переход вместо этого к родительскому прототипу
func=proto[name];
//Если функция была частью этого прототипа
if(func==this[name]) {
//Переход вместо этого к родительскому прототипу
func=v[name];
}
}
//Отслеживание глубины. На которой мы находимся в стеке наследования
depth +=1;
//Вызов исполняемой функции со всеми аргументми, кроме первого (в котором хранится имя исполняемой функции)
ret = func.apply(this. Array.prototype.slice.apply(arguments, [1]));
//Сброс глубины стека
depth -=1;
//Возвращение значения, возвращаемого исполняемой функцией
return ret;
});
return this;
});
Привожу с комментами из книги(они мне не оч помогли) Если есть возможность то можно обьяснить через аську. Помимио общего вопрос как это работает есть пара вопрос с синтаксической точки зрения (зря курил)
Function.prototype.method = function(name, func) {
Function.prototype.method это название функции? Если да то оно что-нибудь значит или просто названо так для удобства. //Отслеживание, на каком уровне глубины в родительских функциях мы находимся Что ещё за глубина? var proto = this.parent = new parent();Что за парент? Вообще когда одна функция наследует метода обьекта (или наоборот(поправте как правильно)) что является родителем и связано это как-то с передаваемым параметром функции
function(parent) {
if(depth){
Что за Если depth то есть если depth что. Звучит как например Если Вася а должно например Если Вася==1 Если Вася существуетИ можно поподробней про метод Apply (ответ что метод Apply похож на call не писать(про него тоже можно расказать)). Вроде всё. |
Первое что попалось на глаза это inhertis вместо inherits. Смотрю дальше, вроде что-то интересное.
|
Цитата:
|
Цитата:
Цитата:
Цитата:
http://javascript.ru/tutorial/object это читали? |
Цитата:
|
После радости от конструкции:
Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};
Function.method("inherits", function(parent) {/*...*/});
сразу пришел в ужас от: var proto = this.parent = new parent(); Либо это что-то очень гениальное, либо книгу пора выкидывать. |
Код написан Дугласом Крокфордом создателем библеотеки JSON как замену XML
Дуглас Крокфорд. это главный архитектор по JavaScript в Yahoo. но и без этого, имно, ему можно ставить памятник уже за один только вот этот кусок кода: function object(o) { function F() {} F.prototype = o; return new F(); } его сайт http://javascript.crockford.com/ Так что скорее гениальное) Прочитал что... В javascript нельзя проверить существование глобальной переменной простым if:
if (x) { ... }
Если x не определен, то конструкция if (x) вызовет ошибку javascript. Так почему работает
if(depth){
|
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Вот здесь:
ret = func.apply(this.Array.prototype.slice.apply(arguments, [1])); this лишний, должно быть так: ret = func.apply(Array.prototype.slice.apply(arguments, [1])); this ссылается на экземпляр дочернего класса, а не на window. |
Цитата:
var a = 0;
if (a) {
alert(1);
}
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Зайдя на сайт Крокфорда я нашёл такой код
Function.method('inherits', function (parent) {
var d = {}, p = (this.prototype = new parent());
this.method('uber', function uber(name) {
if (!(name in d)) {
d[name] = 0;
}
var f, r, t = d[name], v = parent.prototype;
if (t) {
while (t) {
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
} else {
f = p[name];
if (f == this[name]) {
f = v[name];
}
}
d[name] += 1;
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
d[name] -= 1;
return r;
});
return this;
});
А тот код я взял не из книги Крокфорда а из книги Джона Рейсига может он там курнул и решил его подкоректировать. Как вам этот код? |
Цитата:
|
Не знаю бывало с вами такое вроде смутно понимаю как это работает. Как будто ответ где-то рядом но найти не могу.
может постваите комменты к коду мне в помощь? |
Апну тему а то хз то что я сообщение отредактировал отобразилось мож вы думаете что новых сообщений нету. Повторюсь можете к этому коду комменты на русском поставить объясняющие?
|
Цитата:
|
|
Цитата:
|
И всё таки мне интересно как работает этот код моно коменты к нему?
|
Классическое наследование в JavaScript невозможно, а эмуляция его вредна.
Цитата:
|
Непонятно как код вообще работает. Если вам понятно то раскажите пожалуйста
|
Мне непонятно, что вам непонятно, и, соответственно, непонятно, что рассказывать. Если вам непонятно все, то и спрашивайте это все по пунктам.
|
Необычность в следующем:
У всех классов, что от кого-то наследуют, создается метод uber, который запомнил замыканием ссылку на родителя и его экземпляр. При вызове он получает имя, по которому ищет в запомненном экземпляре нужный метод и вызывает его, передавая все параметры кроме имени. Нужно это на тот случай если и родительский и дочерний класс будут содержать метод с одинаковым именем, т. е. метод дочернего класса экранирует одноименный метод в родительском классе, а значит вызвать экранированный метод из родителя через this.method() не получится и тут как раз пригодится uber. В остальном стандартная, криворукая(нынче) реализация наследования, что применялась еще в 90-х. Ее минусы неплохо расписаны в статье, ссылка на которую ниже. Цитата:
zzz, это четвертая часть, точно не помню, но вроде в первых трех есть про call и apply upd: книгу лучше сжечь. |
Цитата:
|
Цитата:
|
zzz,
если вам лень задать конкретные вопросы, всем остальным тем более лень комментировать код. |
Что значит конкретные вопросы мне что перепесать каждуб строку кода или каждое слова кода и везде поставить вопрос А что это делает??? Повторяю я понимаю что этот код должен сделать но я не понимаю как он это делает.
|
Цитата:
|
Уффф... как же обьяснить я понимаю все эти операторты, функции, обьекты но я не понимаю как всё это вместе выдаёт такой результат. Это всё равно что знать цифры и буквы но не понимаать как решается ленейное уровнение
|
| Часовой пояс GMT +3, время: 16:36. |