Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #51 (permalink)  
Старый 15.04.2009, 23:59
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
я-то имел ввиду, что VO(d) не сохраняется поскольку НЕ НУЖЕН , т.к. при очередном вызове через замыкание он создается заново .
Да, верно. Я сбился (белиберду написал, устал, наверное; сам же объяснял, что VO создаётся каждый раз, и тут же "опечатался"; "зачеркнул"). Естественно, VO и Scope создаются каждый раз при вызове.

P.S.: надо бы сделать тег зачёркивания.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 00:06.
Ответить с цитированием
  #52 (permalink)  
Старый 16.04.2009, 11:56
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Тут еще интересно c чисто хозяйственной точки зрения :
а сохраняется ли [[Scope]] (d), если функция d не содержит переменных из своего [[Scope]], в этом случае вроде как бы оно и не нужно тратить память ?
Правда практически на тестах это не проверить никак .

var a = 10;
function b() {
  var c = 20;
  function d() {
    var e = 30;   alert( e);
  }
  d();
  return d;
}
var sav=b();
Ответить с цитированием
  #53 (permalink)  
Старый 16.04.2009, 11:57
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Dmitry A. Soshnikov
Физически же, эта абстракция представлена AO (для функции и eval'a) и Global - для Global'a.
Ещё поправка - eval берёт VO того контекста, в котором он запущен: если из функции - AO, если из Global - Global.

Сообщение от kefi
а сохраняется ли [[Scope]] (d), если функция d не содержит переменных из своего [[Scope]],
Да, сохраняется.

function a() {
  var b = 10;
  function c() {
    function d() {
      alert(b);
    }
  }
}


Функция "с" не использует переменные из внешнего VO (ещё говорят: не имеет свободных переменных). Однако, функция "d" - использует. И черпает из Scope, частью которого является [[Scope]] (т.е. Scope вышестоящего контекста). Для "d", [[Scope]] - это Scope(c), и если в "c" не будет ссылки на вышестоящий контекст (где находится "b"), "d" не увидит "b".
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 12:03.
Ответить с цитированием
  #54 (permalink)  
Старый 16.04.2009, 12:25
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Dmitry A. Soshnikov
Да, сохраняется
Уточню - а сохраняется ли [[Scope]] (d), если функция d и все вложенные в нее функции не содержит переменных из [[Scope]](d) и не содержат операции eval , в этом случае вроде как бы оно и не нужно тратить память ?

И еще аналогичный вопрос :
А сохраняется ли Scope Chain контекста в котором мы сделали замыкание? Тоже, вроде как, ни к чему .
Т.е.
var a = 10;
function b() {
  var c = 20;
  function d() {
    var e = 30;   alert( e);
  }
  d();
  var savB=d; // Scope Chain (b) === [[Scope]](d)    Здесь сохранится ?
  return d;
}
var sav=b();

Последний раз редактировалось kefi, 16.04.2009 в 17:20.
Ответить с цитированием
  #55 (permalink)  
Старый 16.04.2009, 15:19
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Да, сохраняется. В спецификации ничего по этому поводу не сказано, сказано лишь, что [[Scope]] однозначно записывается в функцию при её создании. Однако, может, какие-то реализации могут делать оптимизацию (только в однозначно определённых случаях, когда точно известно, что функция не использует ничего извне), но это лишь предположение. С другой стороны, в функции может стоять if, внутри которого будет eval(...), использующий свойства из [[Scope]]. Или же функция может вызывать себя рекурсивно по имени (имя также находится в [[Scope]]).
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 15:59.
Ответить с цитированием
  #56 (permalink)  
Старый 16.04.2009, 16:47
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

2 Dmitry A. Soshnikov> Это ответ на первый или второй вопрос, во втором случае вроде как незачем сохранять Scope Chain ?
var a = 10;
( function b() {
  var c = 20;
  function d() {
    var e = 30;   alert( e+c+a);
  }
  d();
  var savB=d; // Scope Chain (b) === [[Scope]](d)    Зачем Здесь хранить Scope Chain (b)  ?
  return d;
} ) ()

Последний раз редактировалось kefi, 16.04.2009 в 17:20.
Ответить с цитированием
  #57 (permalink)  
Старый 16.04.2009, 17:02
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
Это ответ на первый или второй вопрос
На оба. Повторю - в спецификации сказано, что [[Scope]] записывается в функцию однозначно при её создании. Всё остальне - можно лишь додумывать, либо анализировать исходники реализаций ECMA.

Возможно, какая-нибудь из реализаций не сохраняет [[Scope]] для оптимизации в функции вида function a() {}. Но, ещё раз, в спецификации ничего не сказано об этом.
__________________
Тонкости ECMAScript
Ответить с цитированием
  #58 (permalink)  
Старый 16.04.2009, 17:33
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

Сообщение от Dmitry A. Soshnikov
в спецификации сказано, что [[Scope]] записывается в функцию однозначно при её создании
Спецификация она, того..., не очень однозначно толкуется :
Может он-то и записывается , но записывается ссылка на него, но его содержимое ... , короче, вот :
var a = 10;
function b() {
  var c = 20;
  function d() {
    var e = 30;   al( e+c+a);
  };
  // Замыкаем на savB
  var savB=d; // Scope Chain (b) === [[Scope]](d)    Зачем Здесь хранить Scope Chain (b)  ?
  savB(); // 60
  c=0;    // Если бы VO(b) законсервировался при замыкании, то это изменение 
          // не оказало бы воздействия на последующий вызов через Замыкание: 
  savB(); // 40 <- Scope Chain (b), т.е. VO(b) - не законсервировался
  return savB;
};
var s=b(); 
s();      //40 <- Scope Chain (b), т.е. VO(b) - Законсервировался, но Global - нет.
Ответить с цитированием
  #59 (permalink)  
Старый 16.04.2009, 19:17
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от Dmitry A. Soshnikov
Возможно, какая-нибудь из реализаций не сохраняет
Запросто. Оптимизация может быть какой угодно, лишь бы внешне всё было в рамках стандарта, функцию можно предварительно проанализировать и не создавать то, что в ней не используется, например, 'arguments'... etc.
Ответить с цитированием
  #60 (permalink)  
Старый 16.04.2009, 21:53
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
Может он-то и записывается , но записывается ссылка на него
Да, это динамическая цепь (есть ещё и статическая; подробней, можно в вики почитать). Найденное в Scope chain значение, всегда будет последним присвоенным (связанным) значением этой переменной. Чтобы это предотвратить (а такие случаи бывают нужны - например, при замыкании счетчика цикла) - создают новую функцию с новым VO - т.е. передают нужное значение (счетчик цикла) параметром в создаваемую функцию.

Сообщение от kefi
// Замыкаем на savB var savB=d;
Просто ссылка. d - уже замыкание.

Сообщение от kefi
Зачем Здесь хранить Scope Chain (b)
Ну а как? - в "d" есть свободные переменные.

Сообщение от kefi
Если бы VO(b) законсервировался при замыкании,
Здесь динамический scope chain, представляющий из себя стек (т.е. найдётся последнее присвоенное значение первого совпавшего имени переменной, начиная с вершины этого стека, т.е. с VO). Поэтому, ничего здесь не "консервируется", как в статическом лексическом контексте.

Сообщение от kefi
//40 <- Scope Chain (b), т.е. VO(b) - Законсервировался, но Global - нет.
Ничего не "законсервировалось" (снова - динамический Scope): "c" имеет правильное, последнее присвоенное, значение - 0, "а" - правильное, последнее, единожды присвоенное, значение - 10.

Сообщение от Zeroglif
Запросто.
Да, теоретически, и по логике вещей, конечно должны. Но, спецификация этого не отмечает. А точно узнать - можно лишь, проанализировав исходники реализаций.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 23:22.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск