Просмотр полной версии : Javascript: вопросы по ООП
[ТЕМА ЗАКРЫТА. Привожу вопросы и ответы на них]
Были такие ВОПРОСЫ (я их переформулировал кучу раз, но смысл такой):
1. Как создается прототип объекта и как реализовано наследование в Javascript?
2. Зачем задавать свойство constructor для прототипа при ПЕРЕзаписи прототипа, и как работает это свойство в контексте наследования в Javascript?
Ответ на вопрос №1
Пример:
function F() {this.prop1 = 'test'; this.prop2 = 2;};
F.prototype; //это простой объект, который создается автоматически при помощи new Object - у прототипа нет свойств конструктора F
F.prototype.__proto__; // указывает на самый верхний объект Object в Javascript, у которого в своем прототипе определены методы toString(), valueOf() и тд, которыми наследуются ВСЕМИ объектами
Из этого можно сделать следующие выводы:
- в Javascript при создании функции-конструктора F создается объект-прототип (F.prototype) со свойством constructor (ниже поясню зачем оно нужно) и внутренней ссылкой __proto__ - это ссылка на самый верхний Object)
- прототип конструктора F - простой объект Object() (что то типа F.prototype = new Object()); но для правильной работы НАСЛЕДОВАНИЯ в Javascript F.prototype содержит ссылку constructor не на Object, а на F
Ответ на вопрос №2
Пример:
function F(){this.prop1 = 'test'; this.prop2 = 2;};
F.prototype = {test: 1};
var f = new F();
f.constructor; //function Object() { [native code] }
f.constructor.prototype.test; //undefined, так как теперь f.constructor.prototype - это ссылка на прототип самого верхнего объекта Object, смотрите строку выше
F.prototype.constructor = F; // так можно "починить" указанную выше ошибку (так уж устроен Javascript)
Выводы:
- При переОПРЕДЕЛЕНИИ прототипа возникает нарушение взаимосвязи в объектах (f.constructor должен указывать на свой конструктор F, и у этого конструктора есть ссылка на прототип; это очень важно, так как в будущем может привести к ошибкам, если использовать f.constructor
- В Javascript прототипу НЕОБХОДИМО иметь ПРАВИЛЬНУЮ ссылку на свой конструктор, чтобы не нарушалась взаимосвязь объектов и правильно работало НАСЛЕДОВАНИЕ
1. Почему прототип объекта не является простым Object?
Пример (тут он явно не просто Object):
function Obj() {}; Obj.prototype;
function a() {};
alert(a.prototype instanceof Object) //true
Почему это не объект?2. В чем разница между прототипом и экземпляром объекта? В консоль они выводятся почти как один и тот же объект (выглядят так, как будто были созданы при помощи одного и того же конструктора)
Пример:
function Obj() {}; var o = new Obj(); o; Obj.prototype;
Смотри:
function Animal() {
this.name = 'имя по умолчанию'
this.type = 'По умолчанию - медведь'
}
var bear = new Animal();
/* Вид bear:
{
name: 'имя по умолчанию',
type: 'по умолчанию медведь'
}
*/
alert(bear.name); alert(bear.type);
bear.name = 'Изменяем имя у bear'
alert(bear.name) // изменили ( в prototype - нет )
/* Смысл в том, что в прототипе содеражться ССЫЛКИ на свойства конструктора, а ново созданом объекте все приватное (мы изменили имя, но в прототипе оно не изменилось)
*/
3. Зачем задавать конструктор для прототипа при ПЕРЕзаписи прототипа?
Пример:
function Obj() {}; Obj.prototype = {}; Obj.prototype.constructor = Obj;
Это уже смотрите задачу, так пример не приведу сходу. Дело в том, что:
function a() {} // Если читали про прототипы вообще, то знаете, что единственное свойство которое есть у прототипов при созданию, это constructor, в твоем коде, ты его меняешь. (опустошаешь, и меняешь)
Про последнее уже не знаю.
P.S. мог что-то неправильно сказать, так что...почитай еще)
Переформулировал вопросы, чтобы было яснее, о чем речь )
B@rmaley.e><e
07.07.2012, 13:01
function MyObject() {}; var o = new MyObject(); o.toString();Ищется свойство toString у объекта o. Если его у него нет — оно ищется у прототипа. У прототипа оно ищется по той же схеме: если у самого объекта прототипа его нет, то смотрится его прототип (прототип прототипа, т.е.) и так далее, пока прототипы есть. В конечном итоге мы дойдём до Object.prototype, чей прототип null.
Как только нужное свойство находится, оно вызывается с объектом o в качестве this.
В конечном итоге мы дойдём до Object.prototype, чей прототип null.
Вот это самое важное, что мне нужно было понять. Спасибо! Остается еще 2 неотвеченных вопроса в топике )
almac,
Дэвид Флэнанган:
Прототипом объекта является значение свойства prototype
функцииконструктора. Все функции имеют свойство prototype, которое ини
циализируется в момент определения функции.
Вот что я пытался сказать) (с. 164я. 5ое издание)
almac,
Дэвид Флэнанган:
Прототипом объекта является значение свойства prototype
функцииконструктора. Все функции имеют свойство prototype, которое ини
циализируется в момент определения функции.
Вот что я пытался сказать) (с. 164я. 5ое издание)
Да, это ясно что у конструктора есть свойство prototype. Интересует как именно происходит инициализация и почему в prototype присваивается не простой Object(), а конструктор прототипа, хотя Стефанов писал кажется про "простой объект"
almac,
Может я тупость сморожу:
Потому что так сделали создатели языка :blink:
Почему прототип объекта не создается при помощи конструктора Object? Непонятно вообще, как он создается (прототип)
Пример (тут он явно не просто Object())
Вы ошибаетесь
function f(){}
alert(f.prototype.__proto__.constructor===Object);//true
Другой вопрос, что у этого Object() ещё создаётся свойство constructor, которое желательно возвращать прототипу при перезаписи.
almac,
Вот еще можете в опере, dragon fly, побаловаться:
http://s52.radikal.ru/i137/1207/06/fb0290440d74.png
Drimogemon
07.07.2012, 14:29
вот первых вот принцип работы не рассматривающий внутренние механизмы.
http://javascript.ru/forum/185323-post1.html
Drimogemon
07.07.2012, 14:33
1. Почему прототип объекта не создается при помощи конструктора Object?
прототип обьекта СОЗДАЕТСЯ при помощь Object. Смотри.
// СОЗДАЛИ прототип ПРИ ПОМОЩИ Object
var prototype = Object({name:'ololo'});
// подключили его к функции Cat
function Cat (){};
Cat.prototype = prototype;
Drimogemon
07.07.2012, 14:38
2. Зачем задавать конструктор для прототипа при ПЕРЕзаписи прототипа?
Пример:
Потому что присоздании каждой функции в её свойстве prototype автоматически создается прототип пустышка, предполагая что эту функцию будут использовать как конструктор.
Он выглядит так
function Cat(){};
Cat.prototype = {constructor:Cat}
ну так сделано чтобы в созданных обьектах была ссылка на конструктор который их создал, и если мы перезаписываем этот прототип ЦЕЛИКОМ (а не просто добавлем в него что-то) то нужно и замутить вот это свойство constructor вручную.
Только один ньюанс, когда оно создавалось автоматчиески оно было скрытым и немеречисляемым при for in ? а когда мы его создаем вручную , то создается обычное перечисляемое свойство, и это геморно слегка.
Вы ошибаетесь
function f(){}
alert(f.prototype.__proto__.constructor===Object);//true
Другой вопрос, что у этого Object() ещё создаётся свойство constructor, которое желательно возвращать прототипу при перезаписи.
1. В чем моя ошибка: прототип объекта НЕ создается при помощи конструктора Object (я вообще не понимаю почему именно так, просто Стефанов совсем противоположное пишет: якобы прототип - это простой объект). Выходит, что прототип тоже создается при помощи своего конструктора (свойство сonstructor)?
А вот прототип прототипа f.prototye.__proto__ - это уже простой объект.
2. "желательно возвращать прототипу при перезаписи". Почему ?
Drimogemon
07.07.2012, 17:16
прототип объекта НЕ создается при помощи конструктора Object
автоматически прототип СОООздается вот так new Object
и это пустой обьект, с одним скрытым свойством.
{__proto__: Object.prototype}
а в Object.prototype уже лежит ссылка constructor на функцию Object
Drimogemon
07.07.2012, 17:21
2. "желательно возвращать прототипу при перезаписи". Почему ?
Чтобы была возможность понять чем создан обьект, каким конструктором.
если уж говорить конкретнее то чтобы можно было реализовывать статические свойства.
function Cat(){
this.constructor.cats ++;
}
Cat.cats = 0;
при создании каждого кота, своство cats будет увеличиваться, типа того, то есть this.constructor нужно чтобы у всех обьектов было общее "хранилеще данных" куда можно что-то сложить общее для всех котов ЕСЛИ ЗАХОЧЕТСЯ ЭТО СДЕЛАТЬ разумеется. ну в общем разные применения.
прототип объекта НЕ создается при помощи конструктора Object
false :lol:
Ответил в топике в самом начале
Ответил в топике в самом начале
Drimogemon
08.07.2012, 00:25
almac,
ты все не правильно понял, хчоешь понят как оно работает открой консоль хрома и смотри там
Интересно стала система +/- в карму работать: Drimogemon аж 5 раз умудрился ТС "-" поставить :)
Drimogemon
08.07.2012, 01:41
хаккер.ru
хаккер.ru
Типа "надо знать как" (как мне тут пару людям + поставить?)
Drimogemon
08.07.2012, 02:24
bes,
ой, я тя минусанул нечайно) хотел полюсануть 5 раз но перепутал и то не сработало
bes,
ой, я тя минусанул нечайно) хотел полюсануть 5 раз но перепутал и то не сработало
Ничего, если хочешь, могу и тебя минусануть :)
прототип обьекта СОЗДАЕТСЯ при помощь Object. Смотри.
*!*
// СОЗДАЛИ прототип ПРИ ПОМОЩИ Object
*/!*
var prototype = Object({name:'ololo'});
// подключили его к функции Cat
function Cat (){};
Cat.prototype = prototype;
уверен?
Drimogemon
08.07.2012, 12:48
уверен
чувак, я написал охрененную обертку для ООП на JS, разумеется я уверен.
я написал охрененную обертку
Поразительная самоуверенность. И в чём же её охрененность? Уж не в том ли, что она не работает в IE<9?
Drimogemon
08.07.2012, 13:39
Раед,
1) в том что она весит 300 байт(!)
2) в том что она позволяет удобно описывать "классы"
3) в том что она позволяет удобно делать наследование
4) в том что она поддерживается всеми браузерами
в том что она поддерживается всеми браузерами
Пардон, устаревшая информация
almac,
ты все не правильно понял, хчоешь понят как оно работает открой консоль хрома и смотри там
"все не правильно понял"
Я переписал формулировку и ответы на вопросы вначале статьи - все это описано в книгах, и проверено в консоли хрома тоже. Что именно я не понял-то? )
чувак, я написал охрененную обертку для ООП на JS, разумеется я уверен.
:lol:
p.s. Какой то негодяй мне минуснул - причем только за то, что я видимо плохо понимаю язык Javascript. Неужели нельзя было просто ответить на вопросы вместо минусования?
almac,
lol.
https://lh5.googleusercontent.com/-qHemavFUEvE/T_m9utydGII/AAAAAAAAAJw/Bm1J6-lbQzg/s946/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE %25D0%25BA.jpg
Нет, тебе минусанули за то, что ты как баран не соглашался с 2-3 людьми.
9xakep, ты такой смелый, но это только в инете... уважай других, даже если они знают меньше тебя, и не понимают то, что ты понимаешь
p.s. видно плохое воспитание, отшлепать бы тебя как следует
Drimogemon
08.07.2012, 22:58
p.s. Какой то негодяй мне минуснул
я кастую мульти атак))))
Drimogemon
08.07.2012, 23:01
almac,
я смелый и в интернете и на яву, суть в том что ты действительно как баран ведешь себюя так упрямо как будто тебе должен кто-то что-то дкоазывать. . я мог бы обосрать тебя и мне бы ни чего за это не было (Казань улица Гагарина 18 кв 30 Соснин Алексей 20 лет 87 кг). НО это ни чего бы мне не дало.
Суть в том чото ты действительно паров бы по убавил, и ДА это метафора, у тебя нет ни каких физических паров, имеется ввиду что когда паравооз быстро едет то у него пары давят на поршни. ок да? я просто на всякий случай разжевал.
теперь по теме, ссылка __proto__ новосозданных олбьектов ведет на то на что ведет ссылка prototype конструктора. это всет. если в конструкторе была ссылка на {a:11} то и ссылка __proto__ обьекта поведет на этот {a:11} ок да?
almac,
ты дурак что ли? Во-первых я посмеялся, что чувак выше поставил тебе 5 минусов, хотя это невозможно. Во-вторых я показал тебе, кто их поставил. В-третьих, тебе реально сколько уже сказали, что прототип создается с помощью Object, а ты хоть и не разбираешься (сам признался) продолжал спорить. отшлепать бы тебя как следует
Пиздец
vBulletin® v3.6.7, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot