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

    подойдем делу с другой стороны:
    ExpandedWrap disabled
      function createPerson(name, age){
          var person = {};
          person.getName = function(){ return name; };      // замыкание name
          person.setName = function(value){ name = value; } // тоже
          person.getAge = function(){ return age; };        // замыкание age
          person.setAge = function(value){ age = value; }   // тоже
          return person;
      }
       
      var gregory = createPerson('Gregory', 42),
          miller = createPerson('Miller', 30);
       
      gregory.getName(); // Gregory
      miller.getName(); // Miller
      gregory.getAge(); // 42
      miller.getAge();  // 30

    как думаешь (2K313), если бы функция имела одно определение для всех экземпляров объектов в данном случае, то как бы можно реализовать такое поведение?
    ну вот возмем к примеру функцию getName, как она возвращает разные значения имени?
    пробую сымитировать одно определение на все объекты, выношу определение функции и присваюваю ссылку на нее, в результате пустая строка:
    ExpandedWrap disabled
      function getName(){ return name; };
       
      function createPerson(name, age){
          var person = {};
          person.getName = getName;     // ссылка на внешнюю функци
          person.setName = function(value){ name = value; }
          person.getAge = function(){ return age; };        // замыкание age
          person.setAge = function(value){ age = value; }  
          return person;
      }
       
      var gregory = createPerson('Gregory', 42),
          miller = createPerson('Miller', 30);
       
      gregory.getName(); // ''
      miller.getName(); // ''
      gregory.getAge(); // 42
      miller.getAge();  // 30

    если не понятно, то объясню вызов getName во втором случае возвращает значение name глобального объекта, в случае броузера это window, т.е. window.name, а в первом случае getName и другие создают замыкания на локальные переменные, и каждый возвращаемый объект создает свою копию функции getName, которая замкнута на свою name, значение которого и возращает.

    жду комментарий можно с картинками :D

    пс. я работаю в бюро ритуальных услуг, делаю гробы, ну там саморезы завернуть или гвоздь забить :lool:
    спросите зачем там программирование? ну как же и там тоже нужен учет :D
    Сообщение отредактировано: Cfon -
      Цитата Cfon @
      как думаешь (2K313), если бы функция
      да думал я об этом уже тоже. :whistle: не хочу опять на пол страницы тут расписывать, поэтому буду краток. ты же в С# шаришь...

      Когда функция-конструктор вызывается, у неё составляется свой [[scope]] (так вроде называется) и там хранятся все текушие переменные (включая и переданные функции параметры и может ещё чего). Так вот, после того как функция своё отработала, все эти значения больше никому не нужны и занимаемая ими память освобождается.

      Когда же на какую-то из этих переменных (главное что она не глобальная, всмысле не window.aaa) есть замыкание (скажем внутри функции getName ), то текущий [[scope]] не уничтожается, а закидывается в <STRUCTUR type="function"> которая была только что создана (когда выполнялась строка getName = function( )... ) Возможно что в этом [[scope]] будет всё лишнее удалено и остануться только те переменные, на которые есть замыкание.

      Таким образом, когда позже вызывается getName( ), у неё есть все замкнутые переменные, значения которых были заданы ещё во время создания этой функции. Но это лишь мои предположения, так что если что не так - я не виноват. :crazy: Получается что тело функции getName должно быть полюбому расспарсено сразу ещё при выполнении функции-конструктора, чтоб знать какие в ней переменные используются и на какие из них есть замыкание.

      Я вот только пока щас ещё не знаю, если внутри функции getName тоже делать присвоение функции (напр. getSupName = function ... и тоже с замыканием на какой нибудь переданный аргумент функции-конструктору (только не name, чтоб было видно что замыкание работает и через голову родителя), то будет ли эта переменная в ней видна??? :whistle:

      Добавлено
      А код тела функции один на всех, который работает с текущей стуктурой <STRUCTUR type="function"> ссылку на которую, перед передачей управления исполняемому коду, закидывается скажем например в регистр eax и таким образом код работает с данными по этому адресу. но код один на всех! :whistle:
        Цитата K313 @
        Я вот только пока щас ещё не знаю, если внутри функции getName тоже делать присвоение функции (напр. getSupName = function ... и тоже с замыканием на какой нибудь переданный аргумент функции-конструктору (только не name, чтоб было видно что замыкание работает и через голову родителя), то будет ли эта переменная в ней видна???

        да будет видна, например:
        ExpandedWrap disabled
          function createPerson(name, age){
              var person = {};
              person.getName = function(){ return name; };      
              person.setName = function(value){ name = value; }
              person.getAge = function(){ return age; };      
              person.setAge = function(value){ age = value; }  
              person.toString = (function(){
                  var s = name + ' is a ';
                  return function(){
                      return s + age + ' years old.';
                  };
              }());
              return person;
          }
           
          var gregory = createPerson('Gregory', 42),
              miller = createPerson('Miller', 30);
           
          gregory.toString(); // Gregory is a 42 years old.
          miller.toString(); // Miller is a 30 years old.


        Добавлено
        Цитата K313 @
        А код тела функции один на всех, который работает с текущей стуктурой <STRUCTUR type="function"> ссылку на которую, перед передачей управления исполняемому коду, закидывается скажем например в регистр eax и таким образом код работает с данными по этому адресу. но код один на всех!

        остается понять почему
        ExpandedWrap disabled
          gregory.getName === miller.getName; // false

        :)
        известно, что функции в JS тоже являются объектами и выражение
        ExpandedWrap disabled
          person.getName = function(){ return name; };

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

          Цитата Cfon @
          остается понять почему
          посмотри от сэда, сообщение #150
          Цитата K313 @
          Тогда при встроенном методе, у каждого foo : <STRUCTUR> лежит ссылка на свой <STRUCTUR type="function">, то есть эта структура <STRUCTUR type="function"> у каждого объекта своя.
            Цитата K313 @
            Цитата Cfon @
            остается понять почему
            посмотри от сэда, сообщение #150
            Цитата K313 @
            Тогда при встроенном методе, у каждого foo : <STRUCTUR> лежит ссылка на свой <STRUCTUR type="function">, то есть эта структура <STRUCTUR type="function"> у каждого объекта своя.

            нет я думаю ты ошибаешься :)
            под структурой что ты имеешь ввиду в JS носит название контекст выполнения функции, в котором сохраняются все локальные переменные функции.
              хотя возможно, что ты прав ;)
              вот что я увидел в Chrome Developer Tools на примере кода из поста №153



              видно что методы каждого объекта имееют скрытое свойство [[FunctionLocation]], которое указывает на общее расположение кода.
              я так понял в книжках имелось ввиду, что сами методы (объекты-функции) у каждого объекта разные, которые имеют набор свойств, в том числе и указатель на сам код.
              также они имеют скрытое свойство [[Scopes]], где определены два объекта: Global и Closure.
              Сообщение отредактировано: Cfon -
                foo : <STRUCTUR> - это описатель самой foo, что это за зверь такой, переменная, объект, функция, undefined или число и так далее. И в этой структуре так же должен лежать адрес на память, где находится <STRUCTUR type="function">, которая уже является описателем самой функции, там уже побольше разных данных нужно держать...

                Цитата Cfon @
                да будет видна, например:
                я не понял, чего ты там хотел сделать...

                я же хотел попробовать наколоть функцию createPerson, чтоб она решила, что никаких замыканий на её текущий [[scope]] и он был бы уничтожен после завершения функции
                ExpandedWrap disabled
                  function createPerson(name, age){
                      var person = {};
                      person.getName = function(){ return 1; };      
                      person.setName = function(value){ return 2; }
                      person.getAge = function(){ return 3; };      
                      person.setAge = function(value){ return 4; }  
                      person.toString = function(){
                          var s = {};
                          s.foo = function(){
                              var u = {};
                             u.foo = function(){ return name; }
                             return u;
                          };
                          return s;
                      };
                      return person;
                  }
                я не знаю какое у javascript при этом поведение должно быть, вернётся потом при вызове
                ExpandedWrap disabled
                  createPerson(name, age).toString().foo().foo();
                наш name или undefined? :popcorn:
                  Цитата K313 @
                  я не знаю какое у javascript при этом поведение должно быть, вернётся потом при вызове
                  ExpandedWrap disabled
                    createPerson(name, age).toString().foo().foo();
                  наш name или undefined? :popcorn:

                  вернется namе, потому что для замыкания не имеет значения глубина вложения функции,все к чему выше (по коду) идет обращение образует замыкание.

                  Прикреплённый файлПрикреплённый файлpic1.png (49,13 Кбайт, скачиваний: 309)

                  Цитата K313 @
                  я же хотел попробовать наколоть функцию createPerson, чтоб она решила, что никаких замыканий на её текущий [[scope]] и он был бы уничтожен после завершения функции
                  Скрытый текст
                  ExpandedWrap disabled
                    function createPerson(name, age){
                        var person = {};
                        person.getName = function(){ return 1; };      
                        person.setName = function(value){ return 2; }
                        person.getAge = function(){ return 3; };      
                        person.setAge = function(value){ return 4; }  
                        person.toString = function(){
                            var s = {};
                            s.foo = function(){
                                var u = {};
                               u.foo = function(){ return name; }
                               return u;
                            };
                            return s;
                        };
                        return person;
                    }

                  наколоть не получится :no:
                  Сообщение отредактировано: Cfon -
                    Цитата Cfon @
                    наколоть не получится
                    а если тело внучки в eval упаковать? :popcorn:
                      Цитата K313 @
                      Цитата Cfon @
                      наколоть не получится
                      а если тело внучки в eval упаковать? :popcorn:

                      хз предпочитаю не юзать ее вообще, также как new Function('код')
                      имхо исполнять код переданный через строку это моветон, поэтому даже не буду предполагать что там дак :)

                      Добавлено
                      меня вот заинтересовало другое :)
                      ExpandedWrap disabled
                        function foo() {
                          return function(){
                           // some code
                          };
                        }
                         
                        var bar1 = foo();
                        var bar2 = foo();
                        ...
                        var barN = foo();

                      будет ли в этом случае ссылки на функции bar1...barN указывать на одно тело или таки каждая имеет свое тело?
                      если сравнивать ссылки, то они указывают на разные функции, как и в случае с указателями на разные объекты
                      ExpandedWrap disabled
                        bar1 === bar2; // false

                      если в консоли Chrome напечатать bar1, то выводит просто определение функции
                      ExpandedWrap disabled
                        function(){
                          // some code
                        };
                      Сообщение отредактировано: Cfon -
                        Цитата Cfon @
                        указывать на одно тело или таки каждая имеет свое тело
                        ты же знаешь моё мнение :whistle: тело одно, структуры <STRUCTUR type="function"> разные.

                        Структура <STRUCTUR type="function"> для foo создаётся ещё во время парсинга, а для return function() каждый раз новая при каждом вызове foo( );
                          Цитата K313 @
                          Цитата Cfon @
                          указывать на одно тело или таки каждая имеет свое тело
                          ты же знаешь моё мнение :whistle: тело одно, структуры <STRUCTUR type="function"> разные.

                          Структура <STRUCTUR type="function"> для foo создаётся ещё во время парсинга, а для return function() каждый раз новая при каждом вызове foo( );

                          да пожалуй что так :)

                          Добавлено
                          рассмотрим на примере
                          ExpandedWrap disabled
                            function compare(a, b){
                                if (a < b){
                                    return -1;
                                }
                                else if (a > b){
                                    return 1;
                                }
                                else {
                                    return 0;
                                }
                            }

                          когда определяется функция, интерпретатор парсит ее проверяет на синтаксис и если все в порядке создает объект в который заносит свойства
                          ExpandedWrap disabled
                            {
                              arguments: null
                              caller: null
                              length: 2
                              name: "compare"
                              prototype: Object
                              __proto__: function ()
                              [[FunctionLocation]]: VM227:1
                              [[Scopes]]: Scopes[1] -> 0: Global
                            }

                          тело, код или порядок выполнения инструкций, лежит по ссылке [[FunctionLocation]]
                          VM227:1 это некий адрес в памяти

                          когда происходит вызов
                          ExpandedWrap disabled
                            var result = compare(10, 5);

                          создается контекст выполнения, в котором формируется цепочка областей видимости [[Scores]] этой функции.
                          далее в [[Scores]] запишется указатель на глобальную область видимость Global, тот что уже создан при определении функции, а также будет создан так называемый объект активизиции, в который будут хранится значения аргументов a=10, b=5, а также arguments.
                          данный объект активизации (точнее его адрес) будет также добавлен в [[Scores]].

                          ну и собственно далее испольнение кода, результат которого будет записан в result.
                          вроде все верно :D

                          пс. позже обрисую происходящее в случае замыкания.
                          Сообщение отредактировано: Cfon -
                            рассмотрим замыкание на примере упрощенной версии функции createPerson:
                            ExpandedWrap disabled
                              var createPerson = function(name){
                                  return {
                                      getName: function(){return name;},
                                      setName: function(value){name = value;}
                                  };
                              };
                               
                              var greg = createPerson('Greg', 42);

                            интерпретатор создает определение функции createPerson, затем идет вызов createPerson('Greg', 42), создается контекст выполнения вида
                            ExpandedWrap disabled
                              {
                              getName: function ()
                                arguments: null
                                caller: null
                                length: 0
                                name: "getName"
                                prototype: Object
                                __proto__: function ()
                                [[FunctionLocation]]: VM241:3
                                [[Scopes]]: Scopes[2]
                                  0: Closure (createPerson)
                                    name: "Greg"
                                  1: Global
                              setName: function ()
                                arguments: null
                                caller: null
                                length: 0
                                name: "setName"
                                prototype: Object
                                __proto__: function ()
                                [[FunctionLocation]]: VM241:4
                                [[Scopes]]: Scopes[2]
                                  0: Closure (createPerson)
                                    name: "Greg"
                                  1: Global
                              __proto__: Object
                              }

                            видно, что отличие от примера без замыкания, в наличие дополнительного объекта Closure в котором хранится наше замыкание.
                            ВСЕ РАЗОБРАЛСЯ! :D
                            да понял я тело всегда одно, спасибо курящая обезьяна! :D
                            Сообщение отредактировано: Cfon -
                              Цитата Cfon @
                              да понял я тело всегда одно
                              это ведь не от нас с тобой зависит, а от того C#-шника, который этот очередной интерпретатор для javascript писал. Захочет он чтоб было много тел, так и будет их много. :wall:

                              Цитата Cfon @
                              спасибо курящая обезьяна!
                              да на здоровье, гробовщик, забивающий шурупы в крышку гроба :yes:
                                Цитата K313 @
                                это ведь не от нас с тобой зависит, а от того C#-шника, который этот очередной интерпретатор для javascript писал.

                                Google Chrome V8 на С++ написан :)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


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