15.04.2009, 23:59
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от kefi
|
я-то имел ввиду, что VO(d) не сохраняется поскольку НЕ НУЖЕН , т.к. при очередном вызове через замыкание он создается заново .
|
Да, верно. Я сбился (белиберду написал, устал, наверное; сам же объяснял, что VO создаётся каждый раз, и тут же "опечатался"; "зачеркнул"). Естественно, VO и Scope создаются каждый раз при вызове.
P.S.: надо бы сделать тег зачёркивания.
Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 00:06.
|
|
16.04.2009, 11:56
|
Кандидат Javascript-наук
|
|
Регистрация: 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();
|
|
16.04.2009, 11:57
|
Профессор
|
|
Регистрация: 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".
Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 12:03.
|
|
16.04.2009, 12:25
|
Кандидат Javascript-наук
|
|
Регистрация: 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.
|
|
16.04.2009, 15:19
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Да, сохраняется. В спецификации ничего по этому поводу не сказано, сказано лишь, что [[Scope]] однозначно записывается в функцию при её создании. Однако, может, какие-то реализации могут делать оптимизацию (только в однозначно определённых случаях, когда точно известно, что функция не использует ничего извне), но это лишь предположение. С другой стороны, в функции может стоять if, внутри которого будет eval(...), использующий свойства из [[Scope]]. Или же функция может вызывать себя рекурсивно по имени (имя также находится в [[Scope]]).
Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 15:59.
|
|
16.04.2009, 16:47
|
Кандидат Javascript-наук
|
|
Регистрация: 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.
|
|
16.04.2009, 17:02
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от kefi
|
Это ответ на первый или второй вопрос
|
На оба. Повторю - в спецификации сказано, что [[Scope]] записывается в функцию однозначно при её создании. Всё остальне - можно лишь додумывать, либо анализировать исходники реализаций ECMA.
Возможно, какая-нибудь из реализаций не сохраняет [[Scope]] для оптимизации в функции вида function a() {}. Но, ещё раз, в спецификации ничего не сказано об этом.
|
|
16.04.2009, 17:33
|
Кандидат Javascript-наук
|
|
Регистрация: 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 - нет.
|
|
16.04.2009, 19:17
|
...
|
|
Регистрация: 09.03.2008
Сообщений: 216
|
|
Сообщение от Dmitry A. Soshnikov
|
Возможно, какая-нибудь из реализаций не сохраняет
|
Запросто. Оптимизация может быть какой угодно, лишь бы внешне всё было в рамках стандарта, функцию можно предварительно проанализировать и не создавать то, что в ней не используется, например, 'arguments'... etc.
|
|
16.04.2009, 21:53
|
Профессор
|
|
Регистрация: 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
|
Запросто.
|
Да, теоретически, и по логике вещей, конечно должны. Но, спецификация этого не отмечает. А точно узнать - можно лишь, проанализировав исходники реализаций.
Последний раз редактировалось Dmitry A. Soshnikov, 16.04.2009 в 23:22.
|
|
|
|