Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #21 (permalink)  
Старый 21.09.2009, 14:06
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от ZoNT
Если вопрос только в этом то надо было писать так:
замыкания опять же нет, вопрос был не в способе запомнить что-то в "new Function", а в том, что там в памяти, запомнен ли чей-то scope.

Последний раз редактировалось Riim, 21.09.2009 в 14:08.
Ответить с цитированием
  #22 (permalink)  
Старый 21.09.2009, 14:11
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Riim
вопрос не в способе запомнить в что-то в "new Function", а в том что там в памяти, запомнен ли чей-то scope
Я подразумеваю, что второе - результат работы первого...Только вот этот самый результат не нужен...
Ответить с цитированием
  #23 (permalink)  
Старый 21.09.2009, 14:20
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

B~Vladi, можно через prototype, можно просто создавать нормальную структуру объектов, так что бы до всего нужного можно было добраться через window.
Ответить с цитированием
  #24 (permalink)  
Старый 21.09.2009, 14:55
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Ладно, не буду вас доставать
Ответить с цитированием
  #25 (permalink)  
Старый 21.09.2009, 15:45
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
замыкания опять же нет, вопрос был не в способе запомнить что-то в "new Function", а в том, что там в памяти, запомнен ли чей-то scope.
Сообщение от ZoNT
Функция через new Function ничего не запоминает
Вообще, каждая функция имеет [[Scope]], просто для функций, созданных с помощью конструктора Function, [[Scope]] содержит только глобальный объект.

А в виду того, что любая функция хранит [[Scope]] (т.е. Scope chain порождающего контекста), все функции являются замыканиями.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 21.09.2009 в 15:47.
Ответить с цитированием
  #26 (permalink)  
Старый 21.09.2009, 17:11
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Dmitry A. Soshnikov
А в виду того, что любая функция хранит [[Scope]] (т.е. Scope chain порождающего контекста), все функции являются замыканиями.
Аха... Тогда ещё такой вопрос:
Есть код:

function fnc1(){
  var i;
  function fnc2(){
    alert(i)
  }
}


А внешний [[scope]], который хранит функция fnc2 - это клон или ссылка на [[scope]] функции fnc1?! Т.е. меня интересует как при этом расходуется память...
Ответить с цитированием
  #27 (permalink)  
Старый 21.09.2009, 17:23
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от B~Vladi
А внешний [[scope]], который хранит функция fnc2 - это клон или ссылка
Ссылка; там же, в статье о замыканиях можно подробно посмотреть.

Сообщение от B~Vladi
или ссылка на [[scope]] функции fnc1?!
Свойство [[Scope]] функции - это ссылка на Scope (Scope chain) порождающего (внешнего) контекста, а не на [[Scope]] внешней функции. Если бы была ссылка на [[Scope]] внешней функции, внутренняя функция не видела бы переменные, объявленные во внешней функции.

Т.е.

f1.[[Scope]] === Scope глобальньного контекста === [Global]


Scope (Scope chain) контекста функции f1 === Объект активации (AO) контекста функции f1 + f1.[[Scope]]:

Scope(f1 Context) == AO(f1 context) + f1.[[Scope]]


А f2.[[Scope]]:

f2.[[Scope]] === Scope(f1 Context) === [AO(f1 context), Global]
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 21.09.2009 в 17:26.
Ответить с цитированием
  #28 (permalink)  
Старый 21.09.2009, 17:42
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Dmitry A. Soshnikov, вот такой у меня вопрос: функция запомнила какие-то переменные, если внутри этой функции создать переменную, одноименную с той, что запомнена, то она как бы экранируется, теперь если экранируется все запомненное за счет имен аргументов, то хранится ли в памяти внешняя функция? Что-то у меня не получается создать пример подтверждающий или опровергающий это. Вот код для пояснения вопроса:
var p = (function() {// func1
	var a = 5, b = 6;
	return function(a, b) {// смысла, хранить в памяти func1, вроде нет, все равно все экранировано, и убрать это экранирование вроде никак (delete применяется к свойствам объектов, но a и b непонятно чьи свойства)
		alert(a + b);
	};
})();

Последний раз редактировалось Riim, 21.09.2009 в 17:47.
Ответить с цитированием
  #29 (permalink)  
Старый 21.09.2009, 18:07
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Riim
если внутри этой функции создать переменную, одноименную с той, что запомнена, то она как бы экранируется
Да, "экранируется", на этом принципе и работает Scope chain.

Т.е. одноимённые переменные (а также, декларации функций и формальные параметры) более глубокого контекста, разрешаются (определяются) раньше, чем переменные с тем же именем, но в контексте выше. Цепь областей видимости контекста (Scope chain) при нахождении в коде переменной, опрашивается интерпретатором от самого глубого звена цепи вверх до глобального объекта (и, в некоторых реализациях, прототипа глобального объекта).

var a = 10;
function A() {
  var a = 20;
  function B() {
    var a = 30;
    alert(a); // найдено сразу в AO(контекста B)
  }
}


Если бы переменная "а" была объявлена один раз (глобально), то при alert(a) из внутренней функции "B", она бы разрешалась по цепи (Scope chain контекста функции "B"):

1. AO(контекста "B") - (нет) ->
2. AO(контекста "А") - (нет) ->
3. VO(Global) === Global - (да) - 10


Сообщение от Riim
теперь если экранируется все запомненное за счет имен аргументов, то хранится ли в памяти внешняя функция
Вообще, теоретически, функцию до создания можно распарсить и посмотреть, используются ли в ней свободные переменные, если нет, то, по идее, можно не создавать замыкание. Но в стандарте об этом ничего не сказано, это просто мысли.

С другой стороны, одна вложенная функция может не иметь свободных переменных, а вложенная во вложенную может, поэтому, надо запоминать всегда, получается:

function A() {
  var a = 10;
  function B() { // нужен ли этой функции Scope A?
    function C() {
      alert(a); // если B не запомнит Scope A, функция С не найдёт "а"
    }
  }
}


Но, повторю, по идее, может быть проведена оптимизация на уровне реализации.

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

Но, стандарт описывает предложение по оптимизации - объединённые объекты:

function a() {
  function b(z) {
    return z * z;
  }
  return b;
}
 
var x = a();
var y = a();


Т.к. [[Scope]] функций x и y - не различим (и вообще, оба объекты - не различимы), реализация вправе использовать объединённые объекты в этом случае, или даже - использовать один объект. Поэтому, не всегда внутренняя функция будет создаваться каждый раз разная.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 21.09.2009 в 18:21.
Ответить с цитированием
  #30 (permalink)  
Старый 21.09.2009, 20:09
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от Dmitry A. Soshnikov
С другой стороны, одна вложенная функция может не иметь свободных переменных, а вложенная во вложенную может, поэтому, надо запоминать всегда
совсем обрубать цепочку, конечно, не стоит, она в любом случае должна закончиться на VO(Global) === Global , я имел в виду аккуратно удалять незначащие звенья в этой цепи, вот здесь, например:
function A() {
  var a = 10;
  function B() { // нужен ли этой функции Scope A?
    function C() {
      alert(a); // если B не запомнит Scope A, функция С не найдёт "а"
    }
  }
}

можно не запоминать AO(контекста "B") и из "C" сразу в "A" ссылаться.
Правда я уже не уверен, что такая оптимизация пойдет на пользу, памяти конечно меньше надо будет, но при каждом создании функции столько дополнительной работы делать, с другой стороны там и так этой работы очень много делается.
Ответить с цитированием
Ответ


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

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