Есть ли разумное объяснение столь чрезмерной сложности наследования в js?
function Wall(){
this.color = "red";
}
function Room(){
this.size = "small";
}
//а теперь я хочу "просто унаследовать объект от объекта", как написано в руководстве.
Room.prototype = Wall;
console.log("Room color", Room.color); //ждем, что будет red, однако оказывается undefined
//Оказывается, нужно поступить намного сложнее
Room.prototype = new Wall(); //Сначала создать экземпляр родителя и связать его с потомком
var room1 = new Room(); //Затем - экземпляр потомка
console.log("room1 color", room1.color); //red. И только теперь оно заработало.
Вывод: нельзя наследовать функцию от функции, можно только экземпляр от функции через другой экземпляр. Почему сделано так сложно? Неужели авторы языка, когда писали спецификацию, не увидели этого? |
Цитата:
какой экземпрляр? чего экземпляр? Цитата:
Цитата:
Цитата:
во загнул Цитата:
А разумное объяснение есть -вы вобще не знаете основ. изучите основы для начала Цитата:
|
Есть, дело в том что яваскрипт был расчитан на написание прогармм в 100 строчек кода максимум так что с ООП они особо не заморачивались..
![]() |
О, я бы с удовольствием изучил основы, чем собственно и занимаюсь. И это вызывает лютую боль между полуплечий. Сейчас задача - понять, как удобно реализуется ООП в JS.
Нельзя наследовать функции? Хорошо, буду наследовать объекты.
var Wall = new function(){
this.color = "red";
}
var Room = new function(){
this.size = "small";
}
Room.prototype = Wall;
console.log(Room.color); //undefined, хотя по логике должен присутствовать
//попробуем самым прямым и логичным способом
Room.prototype.color="white";
console.log(Room.prototype.color, Wall.color);//white, white.
Отлично, теперь я умею легко управлять свойствами предка из потомка. Но зачем??? |
Я далеко не специалист в ООП, и классическое наследование большинства ЯП приводит меня в уныние. А вам оно похоже нравится, потому что вы пытаетесь его отыскать там, где его нет. Вроде как только в ES6 появится обертка над прототипным наследованием, похожая на классическое.
В прототипном вроде есть тонкости и детали, но лично мне кажется, что главное понять то, что все объекты создаются функциями на основании прописанного в функции объекта-прототипа. И всё. Взяли любую функцию, прописали ей прототип, вызвали с new, получили объект с нужной цепочкой прототипов, и соответственно нужными методами и свойствами.
function f(){}
f.prototype = new String();
s = new f();
typeof s.toLowerCase // 'function'
f.prototype.myTest = 'qwerty';
s.myTest; // 'qwerty'
То есть прототипы ставить нужно у функции-конструктора, а не у созданного объекта. |
Цитата:
Цитата:
|
Цитата:
ты создаешь класс (функцию), и задаешь для неё ПРОТОТИП, ЭТАЛОН так сказать, от которого будут все наследовать если различия не указаны явно.
function Animal(){
this.animal = true;
}
function Cat(){
this.cat = true;
}
Cat.prototype = new Animal; // Укажем, что эталоном для Котов будет Животное (создадим его в специальное свойство конструктора котов, таким образом все созданные этим конструктором коты будут ровняться на это животное и стараться быть похожими на него ([B]даже если оно видоизменится кстати[/B]) )
new Cat().animal // true
new Cat().cat // true
тадаааа терь покажу какой в этом прикол
function Animal(){
this.animal = true;
}
function Cat(){
this.cat = true;
}
Cat.prototype = new Animal;
new Cat().ololo // unefined - НИ У КОТОВ НИ У ЖИВОТНЫХ НЕТ ТАКОГО СВОЙСТВА
// что ж все коты будут походить на то эталонное животное которое мы создали в свойство prototype конструктора говорите? хм..
// ну хорошо, тут щас лежит животное, эталон, так сказать для котов, добавлю ка я ему свойство. проверим появится ли оно у котов?
Cat.prototype.ololololololo = 11;
new Cat().ololololololo //11
// хм прикольно, а что если я уже создал 900000 котов, и ТОЛЬКО ПОСЛЕ ЭТОГО добавил в в их прототип новое свойство.. появится ли оно У УЖЕ СОЗДАННЫХ ДДООО этого котов?
|
Если да, то это означает что мы можем добавить в прототип например Массивов какой нить метод который автоматически появятся у всех уже созданных до этого массивов и это будет охуенно.
Напрмиер
Array.prototype.ololo = function(){}
|
Не забываем вызывать конструктор предка
function Wall(){
this.color = "red";
}
function Room(){
Wall.apply(this, arguments)
this.size = "small";
}
console.log("Room color", Room.color);
|
Цитата:
|
Цитата:
|
Почему наследования не происходит? Я проверил, скрипт не создает ошибок.
var Wall = new function(){
this.color = "red";
}
var Room = new function(){
this.size = "small";
}
Room.prototype = Wall; //объявляем, что Room наследуктся от Wall
Room.prototype.color="white"; //можно задать через Wall.color - будет то же самое.
console.log(Room.prototype.color, Wall.color); //Проверили, действительно так.
console.log(Room.color); //Undefined! Опа. Наследования не произошло.
|
А всё, у меня получилось "наследование с помощью цепочек прототипов". Только выглядит это очень грустно.
var Animal = function(){
this.prototype = new function(){//создаем базовый прототип
this.walk = true;
}
}
var Cat = function(){
this.prototype = new Animal();//наследуем от Animal
}
console.log(new Cat().walk);//не получилось
console.log(new Cat().prototype.prototype.walk); //true /A так - работает
Цепочки вида Object.prototype.prototype.prototype.prototype.pro totype.property - неудобны, потому что если убрать элемент из последовательности наследования, то придется редактировать абсолютно все вызовы. |
Цитата:
var Wall = {color:'red'};
var Room = {size:'small', obj: Wall}; //{size:'small', obj: {color:'red'}}
|
Цитата:
var Wall = new function(){
this.color = "red";
} // объявили функцию-конструктор и тут же вызвали её, создался объект со свойством color, присвоили переменной Wall ссылку на этот объект
var Room = new function(){
this.size = "small";
} // объявили функцию-конструктор и тут же вызвали её, создался объект со свойством size, присвоили переменной Room ссылку на этот объект
Room.prototype = Wall; /* здесь мы нифига НЕ объявляем, что Room наследуктся от Wall!
В этой строчке мы записываем в свойство prototype объекта Room ссылку на объект Wall
Ведь свойство объекта prototype - это не прототип объекта! прототип находится в скрытом свойстве [[Prototype]] объекта (в некот. браузерах прототип доступен через свойство __proto__)
*/
Room.prototype.color="white"; /* можно задать через Wall.color - будет то же самое - да, это правда)) ведь Room.prototype и Wall ссылаются на один и тот же объект
*/
console.log(Room.prototype.color, Wall.color); //Проверили, действительно так.
console.log(Room.color); /* Undefined! Опа. Наследования не произошло.
Ну и спрашивается, какого нафик наследования?
Ессессно, у Room нет свойства color, мы же его не присвоили
*/
|
Цитата:
|
Пример наследование из библиотеки createJs с которой сейас работаю
//обьявляем неймспейс
this.createjs = this.createjs||{};
//наследуем
(function() {
//конструктор
var Shape = function(prop) {
//вызов функции инициализации
this.initialize(prop);
}
//наследуем от родителя
var p = Shape.prototype = new createjs.DisplayObject();
//сохраним функцию инициализации родителя, вдруг пригодится
p.DisplayObject_initialize = p.initialize;
//инициализация, по сути конструктор из классического ООП
p.initialize=function(prop){
this.x=prop.x;
this.y=prop.y;
}
// обьявляем новые методы и свойства
p.graphics = null;
p.test = function(){ hello() };
//приватный метод
function hello(){
alert('hello');
}
//записываем в неймспейс
this.createjs.Shape=Shape
})()
хочу разЪяснить один момент.(для новичков) Главный недостаток вышеприведённого примера в том что вызывается конструктор DisplayObject при наследовании. Иногда это нужно, а иногда недопустимо. Эта проблема легко решается. Если вызов контструктора нужен, тогда оставляете var p = Shape.prototype = new createjs.DisplayObject(); А если ненужен, то пишите var p = Shape.prototype = Object.create( createjs.DisplayObject.prototype); + если вам вдруг понадобится вызвать конструктор родителя (иногда используется цепочка конструкторов) вы можете его вызвать через DisplayObject_initialize вот ради этих возможностей и использован трюк с выносом кода конструктора в функцию initialize P.S. Однако я сам использую по возможности функцию класс и я не вижу смысла боятся подобных функций. |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
А что мешает протестить самому? -это несколько строк кода всего
function A(){this.num =10};
function D(){this.num =20};
function B(){}
B.prototype = new A;
var c = new B;
alert(c.num)
B.prototype = new D;
alert(c.num)
|
Цитата:
И я знаю, что произойдет с объектом, если поменять прототип у его конструктора, мне для этого не нужно "несколько строчек" писать, я спрашивал про классы в других язаках программирования. Вы бы проспались сначала, и повнимательнее читать стали, прежде чем позориться. |
father_gorry,
ебать ты нубло |
Цитата:
Причём прототип "строки" к тому что, ты конструктор сделал родителем прототипа , а не прототип родительским объектом ссылки на конструктор? Фленеган 6 издание стр . 226
var F = function (){}
var p = F.prototype
var c = p.constructor
c === F
|
Цитата:
Поэтому прежде чем давать, подобные "советы" подумай десять раз о том как ты позоришься перекручивая и пытаясь выставить всё в другом свете:D |
Цитата:
|
Цитата:
function Test() {} Test.prototype = { a:1, b:2, constructor:Test } Без выделенной части свойство constructor созданного объекта будет указывать не на Test а на Object, тем не менее прототипом созданного объекта будет Test.prototype |
Опять все упоролись по ооп. =\
|
Обсуждают прототипное наследование, но в приведнных примерах кода нет применения instanceof. Зачем вообще такое наследование без instanceof?
|
Цитата:
И заодно, почему нельзя вместо
function A(){this.num =10};
function B(){}
B.prototype = new A;
писать
function B(){
this.prototype = new function(){this.num =10}
};
? Второй вариант ведь намного лаконичнее и проще бы воспринимался! |
Цитата:
Цитата:
|
Вот еще:
"В Javascript функция тоже является объектом". Object.prototype = ... - можно function.prototype =... - ошибка |
Цитата:
|
Цитата:
Цитата:
функция потомок чего? потомку(объекту) можно переопределить прототип после создания ?- Нет Примеров приведено море, хватит чтоб внимательно рассмотреть и понять как работает, а не двигать свои теории. Причём те, на какие ответ был дан однозначный ранее Цитата:
Цитата:
как и где ищутся наследуемые свойства/методы? |
Цитата:
|
Function а не function лол))
|
Цитата:
var red = {color:'red'};
function Circle(){
this.shape = 'circle;
}
Circle.prototype = red;
var redCircle = new Circle();
alert(redCircle.color); // 'red'
red.brightness = 'dark';
alert(redCircle.brightness); // 'dark'
Это - самая основа наследования в JS. Пока вы не разберетесь с этим, любой тролль типа dmitriymar сможет убедительно напудрить мозги, объясняя что прототип - это [[Prototype]], а совсем не prototype, который у constructor, потому что constructor это совсем не конструктор; и только кое-где этот прототип - __proto__. А конструктор - это вообще песня, потому как будучи в той же мере объектом, что и те, которые создает, имеет одновременно с prototype еще и прототип. Прототипы объекта - внутреннее свойство, к нему в целом нельзя обратиться напрямую, для простоты я писал, чтоб вы считали что такого свойства у объектов нет. С прототипами объектов нужно работать через функции-конструкторы, которые эти объекты создают. |
Aves,
Чушь несете. Вам бы для начала разобраться в вопросе, а потом уже других учить. А то нахватались обрывочных знаний, и дополнили их своими ошибочными домыслами. В вашем же примере constructor вновь созданного объекта redCircle - это вовсе не конструктор. Конструктор - функция Circle, а constructor указывает на Object
var red = {color:'red'};
function Circle(){
this.shape = 'circle';
}
Circle.prototype = red;
var redCircle = new Circle();
alert(redCircle.color); // 'red'
red.brightness = 'dark';
alert(redCircle.brightness); // 'dark'
alert( redCircle.constructor == Circle );
alert( redCircle.constructor == Object );
Т.е. constructor - не конструктор. Точно так же можно показать, что prototype - не прототип |
Цитата:
Во намешал, намешал . А где белочки и орешки? Такие изыскания обычно начинаются с эпиграфа: У меня закончились помогающие таблетки, А потом пришла белочка с орешками . И в ходе дружеских посиделок родилась теория:..... Цитата:
Ещё, один фантаст теоретик, несущий свой бред в массы |
Вам самим с собой не надоело общаться, трололо? Где я писал про СВОЙСТВО CONSTRUCTOR у объекта? Я про него вообще не упоминал. Конструктор - это ФУНЦКЦИЯ, СОЗДАЮЩАЯ ОБЪЕКТ. Как выяснить, какая, это другой вопрос.
Если хотите мне что-то попытаться объяснить, хотя бы потрудились понять, о чем я пишу. Хотя можете не напрягаться, на сообщения троллей, которые видят только то,ч то хотят видеть, я больше реагировать не намерен. |
Цитата:
С чего всё начиналось: Цитата:
Еще раз для бредоносной пчелы, возомнивших себя спецом-теоретиком: прототип это прототип, конструктор это конструктор. У прототипа есть свойство конструктор какое указывает на функцию конструктор(не рассматриваем случаи когда не указывает ). И не нужно "изысков" бредовых, для доказательств бреда надуманного |
| Часовой пояс GMT +3, время: 22:36. |