Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наследование, Вызов метода супер класса 
:(
    Опции темы
ZAVS
Дата 24.4.2006, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Насколько я знаю наследование в java-script-е реализуеться с помощью прототипов

Код


function a1(){
    this.print=function(){
        alert("a1");
    }
 }
 
 function a2(){
    this.print=function(){
        alert("a2");    
    }
 }
 a2.prototype=new a1();

var ob1=new a1();
var ob2=new a2();

ob1.print();
ob2.print();



Полсе работы этого скрипта будет 2 алерта

1. a1
2. a2

Так вот вопрос:

как из наследника вызвать метод предка, если предок переписал этот метод??

p.s.
например в java-е используем super
 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 26.4.2006, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Логика не совсем верная. В JS нет классов как таковых, но можно писать "как бы", при этом требуеться чётко знать границу между членами прототипа и собственными членами обьекта. Первые это общие на все обьекты от конструктора свойства, вторые это личные у каждого обьекта свои свойства.

Второй концептуальный момент, в конструкторе создавая методы через this.method = function ты для каждого обьекта создаёшь новую функцию, т.е. этот метод не являеться чем то общим для всех a1. Closures конечно вещь эффективная, так что потерь производительности в принципе нет.

Третьим концептуальным моментом назовём, на первый взгляд кривую, фичу, когда свойство constructor у обьекта сменяеться с A на B если прототипу его конструктора (A) был присвоен другой обьект порождённый от другого конструктора (B). Также следует отметить что все свойства прототипа установленные ранее будут потеряны, мы ведь замещаем его новым обьектом. Лучше перечитать это снова smile

Собираем до кучи всё сказанное выше, соображаем: в JS "ООП" устроен несколько иначе, заменив прототип другим обьектом мы не наследуем, мы в прямом смысле (ну почти smile ) говорим  "этот обьект эквивалентент другому", даже instanceof это докажет.

Ну и заключением всего поста будет код как можно провернуть таки наследование в стиле Java:
Код
//это будет наш предок, обращаем внимание на поле создаваемое в конструкторе
function parentA(val){
    this.value = val;
}
//а это метод *прототипа*, не личное поле как value ;-)
parentA.prototype.print = function(){
   //про личное поле value снова напомню, его нет в прототипе, оно создаёться в конструкторе
   alert("From parent A, value: " + this.value);
}

//подопытный номер два, будет "наследовать" parentA
function childB(){
  //отмечаем момент - нет никакого поля value
  //раз нет классов с конструкторами, нет и "цепочки вызвовов конструкторов" как в Java ;-)
  //для тестов смысла apply (см. ниже) можно здесь поставить
  //this.value = 70
  //и поиграться с типом вызовов на прямую или через apply/call - советую сделать ;-)
}
//parentA и childB совершенно разные конструкторы порождающие разные обьекты со своими разными print
childB.prototype.print=function(){
   alert("From child B, we have no value ;-)");

   //мы этот метод скопируем позже, но если кому то захочеться вызвать print до
   //чудесного превращения childB -> parentA, то предотвратим бесконечную рекурсию
   if(this.constructor.prototype.print != arguments.callee)
      this.constructor.prototype.print.apply(this, arguments); //вызываем метод "предка"
   //почему apply? а потому что это просто функция, на ком вызвали, туда this и укажет.
   //вызовем на прямую this будет указывать на оригинальный обьект-прототип функции parentA
   //напомню оригинальный обьект-прототип это обьект порождённый от конструктора, но
   //при этом не имеющий полей установленных конструктором, т.е. конструктор не отрабатывает.
   //этот обьект существует у всех функций и являеться пустым обьектом пока мы сами
   //прототип не заполним, что мы и делали.
}
var dummy = new childB(); //это ещё old school обьект))
//запомнили эту строчку, естественно alert будет
if(dummy instanceof childB) alert("dummy is childB!");

childB.prototype=new parentA(45);
//конецептуальный момент! =)
if(dummy instanceof childB) alert("dummy is childB!"); //подсказка: ничего здесь не будет
//а почему? а потому что главного якудзу prototype дома childB убил и поставил себя на его место
//выходец из дома parentA. Все созданные ранне обьекты служат прошлому (реально убьёт его сборщик
//мусора когда все порождённые обьекты будут убраны) хозяину, тенью висящий среди них и никто не
//назовёт новый childB своим домом :)

//это телодвижение >перезаписывает< метод print у ранее созданного обьекта parentA, создавая тем
//самым >локальный (собственный для обьекта)< метод(а вообще поле) print.
//при этом помним про замещённый конкструктор childB на childA, следовательно можем добраться до
//прототипа предка. Есессно это всё доступно только для обьектов порождённых после текущих телодвижений.
childB.prototype.print = dummy.print;

var ob1=new parentA(90);
var ob2=new childB();

ob1.print(); //вызвыаем метод прототипа
ob2.print(); //заклинание: "вызываем локальный метод обьекта стоящего в текущий момент прототипом конструктора childB"; повторять до полного просветления.
dummy.print(); //не, ну старые обьекты есессно имеют свой старый обьект прототип и их конструктор никуда не делся
alert(dummy.constructor == childB); //мало того он всё тот же старый childB
alert(childB.prototype.value); //и ведь childB имеет теперь поле (локальное кстати) от обьекта порождённого parentA
alert(dummy.constructor.value); //но таки здесь таки один из редких "магических" моментов JS - value мы не видим, т.к. в constructor у нас лежит instance функции childB со своим старым прототипом.


Медитируем. Совет: не стоит выделывать Java из JS, обратись к изяществу Ruby smile
Помни что классы в Java это в первую очередь прямое отображение "физики" (размеры структур в памяти и т.д.), а т.к. Java с жёсткими типами в корне отличаеться от JS с duck-typing'ом, то приведение параллелей ни к чему хорошему не приведёт. Ruby чистый ООП скриптовый с "динамическими" типами язык. Вот так и стоит писать под JS. Примеры можно глянуть в prototype фреймворке.

Думаю сим длинным постом дал пищу для ума smile

P.S. нашёл в prototype.js пару упущений и один серьёзный глюк, уже задумал prototyped.js на базе первого smile
P.P.S однако заработался... прихожу на форум редко, пишу длиннющие посты... =)    


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ZAVS
Дата 1.5.2006, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Спасибо за пост.

Насколько я понял функция это обьект который отличается от обычных обьектов, у которых есть только поля( свойства, и функции), он имеет несколько другую структуру.

+---------+-------------------+-----------------+
|  тело   |       поля           |прототип      |
+---------+-------------------+-----------------+
| this      |                         | constructor   |
|             |     prototype-> |                      |
|             |                         |                      |
|             |                         |                      |
+---------+-------------------+-----------------+

Как и все обьекты она имеет поля. Вместе с тем она имеет еще тело которое начинает работать когда вызываем функцию, в теле имеются локальные переменные. Она также содержает внутренний обьект прототип.
В полях функции содержится предопределеное переменное-ссылка: prototype который показывает на прототип.
В прототипе содержится предопретеленное переменное constructor который ссылется на тело функции-обьекте, то-есть на функциональную часть.
Функция выполняет также роль класса, при помощи оператора new. При этом создается обьект в полях которого есть поля ссылки на поля прототипа. При создании обьекта вызывается код функции. В нем есть предопределенная локальная переменная ссылка this, которая ссылается уже на поля обьекта который создается.

Если в обьекте изменим значение переменого, который ссылается на одноименное поле прототипа то связ между ними оборвется, то-есть изменив поля прототипа не изменим поле обьекта.

Вопрос:

Насколько мое понимание соответствует действительности??

p.s.
опыты  сделанные мною не противоречат теории smile 
 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 1.5.2006, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ZAVS @  1.5.2006,  00:44 Найти цитируемый пост)
Насколько я понял функция это обьект который отличается от обычных обьектов, у которых есть только поля( свойства, и функции), он имеет несколько другую структуру.

Любая функция являеться instance конструктора Function, который в свою очередь "наследует" от Object. Любая функция это обьект, в JS вообще всё это либо обьект, либо примитив. Примитив не имеет полей как обьект и не может сохранять новые поля, хотя при обращении с ним как с обьектом пользуеться прототипом встроенного wrapper'а (String, Boolean etc).

Откровенно говоря в JS функций нет smile  Есть замыкания, мы оборачиваем некий код который сохраняет свой контекст, затем этот код можно вызвать позже. Замыкая код несколько раз (функция в функции например) мы получаем несколько instances "функции", каждая из которых будет содержать свой контекст - ссылки на видимые переменные.

Цитата(ZAVS @  1.5.2006,  00:44 Найти цитируемый пост)
В прототипе содержится предопретеленное переменное constructor который ссылется на тело функции-обьекте, то-есть на функциональную часть.

Поле constructor предопределено почти у всех обьектов (кроме DOM элементов в ИЕ, отстойничает зараза) (window, location и прочие "legacy" обьекты тоже без конструкторов) и указывает на конструктор обьекта. По конструктору можно добраться до прототипа. Прототип функции это, по дефолту, пустой обьект с полем constructor указывающем на функцию (порождён от функции, но без её запуска).

Цитата(ZAVS @  1.5.2006,  00:44 Найти цитируемый пост)
нем есть предопределенная локальная переменная ссылка this, которая ссылается уже на поля обьекта который создается.

Не совсем, this указывает на любой обьект на котором вызвали функцию. Для примера:
Код
function test() {
   this.message = "I'm test!";
}
test.prototype.method = function() {
   alert(this.message);
}

var b = new test();

var a = {message:"I'm not test!!!"};
b.method.call(a);

var c = {message:"I'm not test too!!!"};
c.method = b.method;
c.method();

//как видим метод это всего лишь поле обьекта содержащее функцию

Цитата(ZAVS @  1.5.2006,  00:44 Найти цитируемый пост)
Насколько мое понимание соответствует действительности??

JS гибкий язык, кто-то пользует его как декларативный, кто то структурно и C подобно, ещё чаще как чистый ООП. Найди свой подход smile    


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ZAVS
Дата 1.5.2006, 02:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Цитата(Sardar @  1.5.2006,  02:18 Найти цитируемый пост)
Откровенно говоря в JS функций нет   Есть замыкания, мы оборачиваем некий код который сохраняет свой контекст, затем этот код можно вызвать позже. Замыкая код несколько раз (функция в функции например) мы получаем несколько instances "функции", каждая из которых будет содержать свой контекст - ссылки на видимые переменные.


Но замыкание все же делается при помощи instancе-ов конструктора Function 
То-есть  instancе-ы Function отличаются от instancе-ов других конструкторов "радикальнее"( грубо говоря )--они умеют оборачивать кодsmile 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 1.5.2006, 02:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ZAVS @  1.5.2006,  01:28 Найти цитируемый пост)
Но замыкание все же делается при помощи instancе-ов конструктора Function 

Угу, как new String породит новый wrapper строки. Только фишка не в этом, а в том что closures обычно пользуют несколько шире чем функции, глянь сюда: http://forum.vingrad.ru/index.php?showtopi...st&p=715636  


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ZAVS
Дата 1.5.2006, 02:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Цитата(Sardar @  1.5.2006,  02:18 Найти цитируемый пост)
Поле constructor предопределено почти у всех обьектов 


a что эсли это поле просто ссылка на соответствующее поле прототипа, как ссылки на другие поля прототипа?? 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 1.5.2006, 02:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ZAVS @  1.5.2006,  01:36 Найти цитируемый пост)
a что эсли это поле просто ссылка на соответствующее поле прототипа, как ссылки на другие поля прототипа??  

Оно себя так и ведёт. Одно всегда верно, пользовательский обьект не может не иметь конструктора и от этого конкструктора можно всегда создать новый обьект + работать с прототипом. 


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ZAVS
Дата 1.5.2006, 02:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Цитата(Sardar @  1.5.2006,  02:33 Найти цитируемый пост)
Только фишка не в этом, а в том что closures обычно пользуют несколько шире чем функции, глянь сюда: http://forum.vingrad.ru/index.php?showtopi...st&p=715636   


не понимаю, что имеешь в виду, смотрю на топик и ничего необычного не вижу
 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 1.5.2006, 03:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Ну вот ещё пример: http://forum.vingrad.ru/index.php?showtopi...st&p=677242
Вообще вся тема интересна. 


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
ZAVS
Дата 1.5.2006, 03:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 25.2.2004
Где: ЕРЕВАН

Репутация: нет
Всего: 1



Цитата(ZAVS @  1.5.2006,  02:50 Найти цитируемый пост)
Только фишка не в этом, а в том что closures обычно пользуют несколько шире чем функции, 


То-есть используют код в "контексте" обьекта несколько шире чем в "контексте" функции? 
--------------------
Учись студент доцентом станешь :)
PM MAIL ICQ   Вверх
Sardar
Дата 1.5.2006, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(ZAVS @  1.5.2006,  02:17 Найти цитируемый пост)
То-есть используют код в "контексте" обьекта несколько шире чем в "контексте" функции?  

Перечитал фразу несколько раз... слишком широко охватывает понятия контекстов, и вообще чую "не туда идём" smile

В JS closures ведут себя также как везде, где они реализованы, т.е. замыкаеться некий код в некую "функцию" + сохраняються все видимые ссылки на переменные. Именно ссылки, т.к. значения переменных могут потом измениться, это всё доступно и "видно" из замыкания. Теперь добавь сюда особенность ссылки this указывать на "нечто" на ком вызвали замыкание - получили обьекты с методами. Также добавь сюда особенность функций с оператором new, который создаёт пустой обьект, связывает поле constructor с функцией родителем и вызывает функцию на новом обьекте - получили конструкторы обьектов.

Это то что реально происходит. Дальше в эту модель можно внести наработанные приёмы типа приватных полей и методов обьектов. Это бывает удобно, хотя всегда "понарошку" т.к. процессы лежащие за приёмом создают только видимость + свои side effects. Это редко было проблемой, гораздо чаще встречаеться наоборот не использование выразительности JS, т.к. не сразу удаёться "врубиться" в приёмы (методология) декларативных языков.

Стоит увлечся этим: Ruby, Python и Groovy 


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0558 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.