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, время: 23:04. |