На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ElcnU, ANDLL, fatalist
Страницы: (11) [1] 2 3 ...  10 11 все  ( Перейти к последнему сообщению )  
> функциональное наследование , по мотивам Дугласа Крокфорда
    Всем здрасте, новая трабла, след код выводит
    ExpandedWrap disabled
      Gregory is a 42 years old. undefined is a friend.

    почему "undefined"?
    ExpandedWrap disabled
      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.
      })();
    Сообщение отредактировано: Cfon -
      ExpandedWrap disabled
        s += obj.friends[i].name + ', ';

      Что за свойство name и откуда оно возьмется?
        Цитата AVA12 @
        ExpandedWrap disabled
          s += obj.friends[i].name + ', ';

        Что за свойство name и откуда оно возьмется?

        это свойтсво объекта obj, смотри что я передаю в createPerson:
        ExpandedWrap disabled
          var gregory = createPerson({ name: 'Gregory', age: 42, friends: [] });

        вот структура объекта
        ExpandedWrap disabled
          { name: 'Gregory', age: 42, friends: [] }

        friends - массив объектов

        Добавлено
        а все разобрался ошибка восприятия :D
        заменил на getName терь все пучком :victory:
        ExpandedWrap disabled
                  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 :D
        Сообщение отредактировано: Cfon -
          продолжаю тему, в предыдущем примере собственно наследования как такового и не было.
          короче делаю функциональное наследование таким образом:
          ExpandedWrap disabled
                
                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

          выхлоп:
          ExpandedWrap disabled
            Out of stack space

          я так понял идет рекурсивный вызов toString(), вопрос в том как мне теперь быть? мне надо вызвать метод toString() базового объекта person, в переопеределяемом методе toString().
          надеюсь нормально объяснил :blink:
          Сообщение отредактировано: Cfon -
            сам все порешал :D
            решение гениальное! надо просто сохранить ссылку на базовый метод toString :D
            ExpandedWrap disabled
                  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;
                  };
            Сообщение отредактировано: Cfon -
              так все просто замечательно объекты создаются, наследуются, но одно маленькое но, в моем случае методы объектов дублируются в каждом вновь создаваемом объекте и как я понимаю расходуют впустую память, а хотелось бы чтобы они были в единственном экзампляре!
              идеи есть? будем думать :D
              Сообщение отредактировано: Cfon -
                методы не дублируются, в объектах создаются ссылки на каждый метод
                  Цитата K313 @
                  методы не дублируются, в объектах создаются ссылки на каждый метод

                  в каждом объекте созданном через createPerson или createJavaDrocher у каждого будет свой индивидуальный набор методов.
                    так вот что я придумал, можно вынести реализацию методов в отдельный объект и потом дергать их из других объектов:
                    ExpandedWrap disabled
                          // это общий объект в котором реализованы методы
                          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, таким нехитрым способом мы сократили объем памяти, которые будут занимать эти объекты :victory:
                    конечно в данном гипотетическом случае это не видно, но если представить реальные объекты это будет заметно.

                    пс. в случае с короткими метода такими как getName и тп, возможно не стоит заморачиваться, но ради соблюдения целостности интерфейса, можно и их перенести в общую реализацию.
                    Сообщение отредактировано: Cfon -
                      Цитата Cfon @
                      у каждого будет свой индивидуальный набор методов
                      смысл ООП как раз в том, чтобы этого избежать.
                        Цитата K313 @
                        Цитата Cfon @
                        у каждого будет свой индивидуальный набор методов
                        смысл ООП как раз в том, чтобы этого избежать.

                        дык избежал же не? :D
                        ты ваще рубишь JavaScript или просто свои высеры сюда суешь? :D
                        Сообщение отредактировано: Cfon -
                          Агрессивность, самонадеянность и вульгарность - даже для пионЭра это перебор.
                            Цитата AVA12 @
                            Агрессивность, самонадеянность и вульгарность - даже для пионЭра это перебор.

                            ну а че он туфту несет?
                            где тут у меня ООП?
                            наверное даже код не смотрел и пишет стандартные фразы! бесит! :D
                              меня просто твоя гениальнось поразила
                              Цитата Cfon @
                              решение гениальное! надо просто сохранить ссылку на базовый метод toString

                              и мне от зависти захотелось подосрать. :D

                              А если серьёзно, то если бы я писал интерпретатор и компилятор для Javascript, то я бы на твоё объявление функции, создал в памяти блок с исполняемым кодом { телом твоей функции } плюс блок в памяти для всех объявленных переменных в теле функии ( каждая из которых позже при исполнении вызова функции, будут содержать ссылки на адреса в памяти, где хранятся их значения ).

                              Затем, когда ты при каждом новом вызове createPerson внутри функции присваиваешь
                              ExpandedWrap disabled
                                javaDrocher.toString = function () {            
                                            return toString() + ' The grade is ' + obj.grade + '.'; //<-- а тут вызываем его
                                        };
                              я не буду в памяти создавать копию исполняемого кода функции javaDrocher.toString, у меня уже есть этот код в памяти в единственном экземпляре, я его создал во время компиляции, поэтому я просто присваиваю javaDrocher.toString = ссылка на адрес в памяти где находится исполняемый код. И так хоть стописоттыщьраз.

                              Поэтому я и не пойму, где ты там память экономишь...
                                Цитата K313 @

                                ясно, бла бла бла :D

                                Добавлено
                                Цитата K313 @
                                Поэтому я и не пойму, где ты там память экономишь...

                                ну если ты не разбираешься в JavaScript, как я тебе могу объяснить где я там экономлю?!
                                мы же на разных языках разговариваем :D
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (11) [1] 2 3 ...  10 11 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0445 ]   [ 16 queries used ]   [ Generated: 19.04.24, 20:17 GMT ]