Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.227.24.209] |
|
Страницы: (11) [1] 2 3 ... 10 11 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Всем здрасте, новая трабла, след код выводит
Gregory is a 42 years old. undefined is a friend. почему "undefined"? var main = (function () { var createPerson = function (obj) { var person = {}; person.getName = function () { return obj.name; }; person.getAge = function () { return obj.age; }; person.addFriend = function (friend) { obj.friends.push(friend); }; person.toString = function () { var s = ''; var len = obj.friends.length; if (len > 0) { for (var i = 0; i < len; ++i) { s += obj.friends[i].name + ', '; } s = s.slice(0, s.length - 2); s += (len > 1) ? ' are friends.' : ' is a friend.'; } return obj.name + ' is a ' + obj.age + ' years old. ' + s; }; return person; }; var gregory = createPerson({ name: 'Gregory', age: 42, friends: [] }); var shelby = createPerson({ name: 'Shelby', age: 27, friends: [] }); gregory.addFriend(shelby); //<-- тут добавляем объект shelby, но он не появляется в списке друзей console.log(gregory); // Gregory is a 42 years old. undefined is friend. console.log(shelby); // Shelby is a 27 years old. })(); |
Сообщ.
#2
,
|
|
|
s += obj.friends[i].name + ', '; Что за свойство name и откуда оно возьмется? |
Сообщ.
#3
,
|
|
|
Цитата AVA12 @ s += obj.friends[i].name + ', '; Что за свойство name и откуда оно возьмется? это свойтсво объекта obj, смотри что я передаю в createPerson: var gregory = createPerson({ name: 'Gregory', age: 42, friends: [] }); вот структура объекта { name: 'Gregory', age: 42, friends: [] } friends - массив объектов Добавлено а все разобрался ошибка восприятия заменил на getName терь все пучком person.toString = function () { var s = ''; var len = obj.friends.length; if (len > 0) { for (var i = 0; i < len; ++i) { s += obj.friends[i].getName() + ', '; //<-- тут заменил } s = s.slice(0, s.length - 2); s += (len > 1) ? ' are friends.' : ' is a friend.'; } return obj.name + ' is a ' + obj.age + ' years old. ' + s; }; вот так можно obj.name, а вот так уже нельзя obj.friends[i].name |
Сообщ.
#4
,
|
|
|
продолжаю тему, в предыдущем примере собственно наследования как такового и не было.
короче делаю функциональное наследование таким образом: var createJavaDrocher = function (obj) { var javaDrocher = createPerson(obj); //<-- получаем базовый объект person javaDrocher.getGrade = function () { return obj.grade; }; // переопределяем toString, но в нем надо вызвать toString объекта person! javaDrocher.toString = function () { return javaDrocher.toString() + ' The grade is ' + obj.grade + '.'; //<-- тут хз рекусия }; return javaDrocher; }; var gregory = createJavaDrocher({ name: 'Gregory', age: 42, grade: 10, friends: [] }); console.log(gregory.toString()); //<-- выводит ошибку: Out of stack space выхлоп: Out of stack space я так понял идет рекурсивный вызов toString(), вопрос в том как мне теперь быть? мне надо вызвать метод toString() базового объекта person, в переопеределяемом методе toString(). надеюсь нормально объяснил |
Сообщ.
#5
,
|
|
|
сам все порешал
решение гениальное! надо просто сохранить ссылку на базовый метод toString var createJavaDrocher = function (obj) { var javaDrocher = createPerson(obj); var toString = javaDrocher.toString; //<-- сохраняем ссылку на базовый toString javaDrocher.getGrade = function () { return obj.grade; }; javaDrocher.toString = function () { return toString() + ' The grade is ' + obj.grade + '.'; //<-- а тут вызываем его }; return javaDrocher; }; |
Сообщ.
#6
,
|
|
|
так все просто замечательно объекты создаются, наследуются, но одно маленькое но, в моем случае методы объектов дублируются в каждом вновь создаваемом объекте и как я понимаю расходуют впустую память, а хотелось бы чтобы они были в единственном экзампляре!
идеи есть? будем думать |
Сообщ.
#7
,
|
|
|
методы не дублируются, в объектах создаются ссылки на каждый метод
|
Сообщ.
#8
,
|
|
|
Цитата K313 @ методы не дублируются, в объектах создаются ссылки на каждый метод в каждом объекте созданном через createPerson или createJavaDrocher у каждого будет свой индивидуальный набор методов. |
Сообщ.
#9
,
|
|
|
так вот что я придумал, можно вынести реализацию методов в отдельный объект и потом дергать их из других объектов:
// это общий объект в котором реализованы методы var Person = { getName: function () { return this.name; }, getAge: function () { return this.age; }, addFriend: function (friend) { this.friends.push(friend); }, toString: function () { var s = ''; var len = this.friends.length; if (len > 0) { for (var i = 0; i < len; ++i) { s += this.friends[i].getName() + ', '; } s = s.slice(0, s.length - 2); s += (len > 1) ? ' are friends.' : ' is a friend.'; } return this.name + ' is a ' + this.age + ' years old. ' + s; } }; // тут мы дергаем методы из объекта Person var createPerson = function (obj) { var person = {}; person.getName = function () { return Person.getName.call(obj); //<-- тут можно было не заморачиваться и юзать obj.name }; person.getAge = function () { return Person.getAge.call(obj); }; person.addFriend = function (friend) { Person.addFriend.call(obj, friend); }; person.toString = function () { return Person.toString.call(obj); //<-- вместо большого кода мы просто дергаем метод toString из Person }; return person; }; var gregory = createPerson({ name: 'Gregory', age: 42, friends: [] }); var shelby = createPerson({ name: 'Shelby', age: 27, friends: [] }); console.log(gregory); console.log(shelby); два объекта юзают реализацию методов Person, таким нехитрым способом мы сократили объем памяти, которые будут занимать эти объекты конечно в данном гипотетическом случае это не видно, но если представить реальные объекты это будет заметно. пс. в случае с короткими метода такими как getName и тп, возможно не стоит заморачиваться, но ради соблюдения целостности интерфейса, можно и их перенести в общую реализацию. |
Сообщ.
#10
,
|
|
|
Цитата Cfon @ смысл ООП как раз в том, чтобы этого избежать. у каждого будет свой индивидуальный набор методов |
Сообщ.
#11
,
|
|
|
Цитата K313 @ Цитата Cfon @ смысл ООП как раз в том, чтобы этого избежать.у каждого будет свой индивидуальный набор методов дык избежал же не? ты ваще рубишь JavaScript или просто свои высеры сюда суешь? |
Сообщ.
#12
,
|
|
|
Агрессивность, самонадеянность и вульгарность - даже для пионЭра это перебор.
|
Сообщ.
#13
,
|
|
|
Цитата AVA12 @ Агрессивность, самонадеянность и вульгарность - даже для пионЭра это перебор. ну а че он туфту несет? где тут у меня ООП? наверное даже код не смотрел и пишет стандартные фразы! бесит! |
Сообщ.
#14
,
|
|
|
меня просто твоя гениальнось поразила
Цитата Cfon @ решение гениальное! надо просто сохранить ссылку на базовый метод toString и мне от зависти захотелось подосрать. А если серьёзно, то если бы я писал интерпретатор и компилятор для Javascript, то я бы на твоё объявление функции, создал в памяти блок с исполняемым кодом { телом твоей функции } плюс блок в памяти для всех объявленных переменных в теле функии ( каждая из которых позже при исполнении вызова функции, будут содержать ссылки на адреса в памяти, где хранятся их значения ). Затем, когда ты при каждом новом вызове createPerson внутри функции присваиваешь javaDrocher.toString = function () { return toString() + ' The grade is ' + obj.grade + '.'; //<-- а тут вызываем его }; Поэтому я и не пойму, где ты там память экономишь... |
Сообщ.
#15
,
|
|
|
Цитата K313 @ ясно, бла бла бла Добавлено Цитата K313 @ Поэтому я и не пойму, где ты там память экономишь... ну если ты не разбираешься в JavaScript, как я тебе могу объяснить где я там экономлю?! мы же на разных языках разговариваем |