Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #41 (permalink)  
Старый 12.04.2009, 19:35
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Сообщение от kefi
контекстом функции
Контекст исполнения (execution context) - некая абстракция, изолирующая одну часть исполняемого кода от других частей в зависимости от того, что это за код. Исполняемый код лексически делится на три части - Global code, Function code, Eval code, отсюда и три вида контекста исполнения, по которым бродит js-интерпретатор. Контексты формируют стек, запустили сам скрипт - вошли в глобальный контекст, запустили функцию - вошли в контекст этой функции, запустили вложенную функцию - вошли в контекст вложенной функции, вернули что-то из вложенной - вышли из контекста вложенной и вернулись в контекст внешней, вернули что-то из внешней - вышли из контекста внешней и вернулись в глобальный контекст, отработал сам скрипт - вышли из глобального контекста... В любой точке сущестует один единственный активный/работающий контекст исполнения.

Сообщение от kefi
объектом переменных
Если говорить об именах, то js - это мир свойств. Переменные, параметры и имена объявленных функций должны стать свойствами некого объекта. Специально для них создаё(ю)тся объект(ы).

Сообщение от kefi
[[scope]] функции
тест
Ответить с цитированием
  #42 (permalink)  
Старый 13.04.2009, 00:19
Кандидат Javascript-наук
Отправить личное сообщение для kefi Посмотреть профиль Найти все сообщения от kefi
 
Регистрация: 12.03.2009
Сообщений: 148

2 Zeroglif >
мда, что-то мутно там.

Мог бы кто понятно объяснить эти [[scope]], VO, контекст и иже с ними (какие-то, оказывается, еще спец объекты бывают ... ) , какие из этих объектов когда создаются, что они содержат и какие из них свойствами каких являются :
- при доRUN-time'оых FD определениях функций ,
- при FE определениях функций ,
- при вызове функций ?

Последний раз редактировалось kefi, 13.04.2009 в 00:22.
Ответить с цитированием
  #43 (permalink)  
Старый 13.04.2009, 12:11
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Вообще, там достаточно информации было, но попробую ещё проще; по частям, чтобы "уварилось". Начнём с VO.

Variable object (Объект переменных, сокращённо VO) - это объект, служащий хранилищем для:

1. переменных (var);
2. деклараций функций (function declaration, FD);
3. формальных параметров функции;

Главной особенностью здесь является то, что VO наполняется при входе в контекст, т.е. до выполнения кода контекста. Причём, в случае var'ов и недостающих формальных параметров под "наполнением" подразумевается резервирование слотов в VO со значением undefined.

Пример:

function test(a, b) {
  var c = 10;
  function d() {}
  var e = function _e() {};
  (function x() {});
}

test(10); // вызов


Этапы вызова:

1. Вход в контекст:

VO = {  // упрощённо; в реале он "наследуется" от Объекта активации
  a: 10,
  b: undefined,
  c: undefined,
  d: <reference to functionBody>
  e: undefined
};


2. Исполнение контекста:

VO['c'] = 10;
VO['e'] = <reference to "_e" functionBody>;


Всё. Как видим, функция "x", являясь FE (function expression), а не FD, не попала в VO (поскольку, ничего не было сказано про воздействие FE на VO в пунктах выше). Если попробовать вызвать функцию "x" за пределами объявления - будет ReferenceError. С другой стороны, "_e" также является FE, но последующее присвоение её переменной "e" оставляет на неё ссылку через VO["e"].

Если здесь всё понятно, и есть желание дальше изучать, можно будет продолжить.

update:

Эм.. Оказывается, я уже в этой теме писал почти тоже самое.
__________________
Тонкости ECMAScript

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

Сообщение от Dmitry A. Soshnikov
Если здесь всё понятно, и есть желание дальше изучать, можно будет продолжить.
Да, VO, вроде понятно, но возник еще объект активации AO...
а еще есть arguments, [[scope]] , etc ... Да, и еще бы понять, чьи они свойства - если функции , то в глобальном контексте если находимся - тогда чьи ?

Последний раз редактировалось kefi, 13.04.2009 в 13:03.
Ответить с цитированием
  #45 (permalink)  
Старый 13.04.2009, 23:26
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
но возник еще объект активации AO...
Activation object (Объект активации, AO) касается только контекста исполнения типа "Функция".

Кстати, в предыдущем посте, говоря о VO, в большей мере имелся в виду VO функции.

AO создаётся при входе в контекст функции и инициализируется свойством arguments, значением которого является Arguments object (Объект аргументов, обозначим ArgO, чтобы не путать с AO):

AO = {
  arguments: <ArgO>
};


Далее, этот AO становится ничем иным как VO. Поэтому, говоря о VO в контексте типа "функция", можно использовать и терминологию AO, т.к. здесь VO === AO. Образно в предыдущем посте (чтобы не перегужать и не приплетать arguments) я назвал это "наследуется", физически же, это тот же самый объект.

Говоря о VO в глобальном контексте, - сам глобальный объект является VO (в браузере - window).

Сообщение от kefi
а еще есть arguments,
Arguments object (ссылка выше) - объект, находящийся в VO/AO функции; содержит свойства:

- callee - ссылка на выполняемую функцию;
- length - количество реально переданных параметров;
- свойства-индексы (числовые, приведённые к строке), значения которых есть формальные параметры функции (слева направо в списке параметров). Количество этих свойств-индексов == arguments.length. Значения свойств-индексов объекта arguments и присутствующие формальные параметры - взаимозаменяемы:

function a(x, y, z) {
  alert(arguments.length); // 2
  alert(arguments.callee === a); // true
  alert(x === arguments[0]); // true
  alert(x); // 10
  arguments[0] = 20;
  alert(x); // 20
  x = 30;
  alert(arguments[0]); // 30
}

a(10, 20);


Сообщение от kefi
Да, и еще бы понять, чьи они свойства - если функции , то в глобальном контексте если находимся - тогда чьи ?
Если код входит в контекст функции, то это свойства функции. Если мы находимся в глобальном коде, то сам глобальный объект - есть VO.

Если всё понятно, можно будет продолжить про [[Scope]].
__________________
Тонкости ECMAScript

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

Я понял так , еще немного допридумал, чтобы было логичнее, проверьте что не так :

Variable object (Объект переменных, сокращённо VO) - это объект, служащий хранилищем для:

1. переменных (var);
2. деклараций функций (function declaration, FD);
3. формальных параметров функции;

Главной особенностью здесь является то, что VO наполняется при входе в контекст, т.е. до выполнения кода контекста. Причём, в случае var'ов и недостающих формальных параметров под "наполнением" подразумевается резервирование слотов в VO со значением undefined.

Для глобального контекста :
VO===Global (где Global - встроенный глобальный объект) нашпиговывается ДО run-time слотами, которые по мере работы программы могут менять свои значения, но не свое количество или имена !

Для функции :
Если не было входа управления в контекст функции, то не существует для нее никакого ни VO, ни AO.
Если управление вошло во внутренний контекст функции F , то ДО ее выполнения для этой функции создается свой VO', при этом выполняются след шаги :
arguments = [<0аргумент>,<1аргумент,...];
 arguments.callee=F;
 arguments.length=<КолвоАргументовФункции_F>;
  AO = {  arguments: arguments };
  F.VO=AO;

При выходе из контекста функции выполняется :
delete F.VO
Цитата:
Если всё понятно, можно будет продолжить про [[Scope]].
"Огласите весь список, пожалуйста."

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

Сообщение от kefi
Для глобального контекста :
VO===Global (где Global - встроенный глобальный объект) нашпиговывается ДО run-time слотами, которые по мере работы программы могут менять свои значения, но не свое количество или имена !
До исполнения, если встречаются: var и FD. Всё остальное (например, a = 10 (без var), либо явно - window.a = 10) - создаётся в runtime'e (и слот и его значение). Поэтому, Global свободно может менять свои слоты и значения этих слотов в runtime'e.

Сообщение от kefi
Если не было входа управления в контекст функции, то не существует для нее никакого ни VO, ни AO.
Да, так. Однако, [[Scope]] в функции зашит изначально и навсегда, не важно, будет ли запущена функция или нет.

Сообщение от kefi
Если управление вошло во внутренний контекст функции F , то ДО ее выполнения для этой функции создается свой VO', при этом выполняются след шаги :
Да.

Сообщение от kefi
F.VO=AO;
Можно и так, для удобства (абстрактно) обозначить.

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

Сообщение от kefi
"Огласите весь список, пожалуйста."
[[Scope]] - это иерархическая цепь Объектов переменных (VO), стоящих выше контекста функции; цепь записывается свойством в функцию при её создании.

Scope (Scope chain, Иерархия областей видимости (в данном переводе)) - это цепь Объектов переменных, в которой происходит поиск значений при разрешении имен идентификаторов. Данная цепь создаётся при выполнении функии, и состоит из VO(текущей функции) и [[Scope]] функции:

Scope = VO + [[Scope]].

Можно ещё раз здесь почитать.

Пример:

var a = 10;
function b() {
  var c = 20;
  function d() {
    var e = 30;
    alert(a + c + e);
  }
  d();
  return d;
}
b();


Имеем:

VO(Global):

VO(Global) === Global = {
  a: 10
  b: <reference to functionBody>
};


При создании "b", [[Scope]] "b":

[[Scope]](b) = [
  VO(Global)
];


VO(b):

VO(b) = {
  c: 20,
  d: <reference to functionBody>
};


При запуске "b", Scope(b) = VO(b) + [[Scope]](b):

Scope(b) = [
  VO(b),
  VO(Global)
];


При создании внутрененней функции "d", [[Scope]] "d":

[[Scope]](d) = [
  VO(b),
  VO(Global)
];


VO(d):

VO(d) = {
  e: 30
};


При запуске "d", Scope(d) = VO(d) + [[Scope]](d):

Scope(b) = [
  VO(d),
  VO(b),
  VO(Global)
];


Разрешение имён идентификаторов "a", "c" и "e" при alert'e:

- "a"
-- VO(d) - не найдено;
-- VO(b) - не найдено;
-- VO(Global) - найдено - 10.


- "с"
-- VO(d) - не найдено;
-- VO(b) - найдено - 20.


- "е"
-- VO(d) - найдено - 30;


Т.е. Scope опрашивается по цепи вверх, если идентификатор не найден в родном VO.

При return d; остаётся ссылка на [[Scope]](d), поэтому все VO в цепи, стоящие иерархически выше - остаются в памяти.
__________________
Тонкости ECMAScript

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

2 Dmitry A. Soshnikov >

Все яснее и яснее, Я сам-то мучился с этими терминами, понимал для себя только , что есть внешний контекст для каждой функции и внутренний. И как это все Вы поняли из ECMA спецификации , ума не приложу ...

Кстати контекст, как я сейчас понимаю, не является термином обозначающим некий объект, это чисто лексический контекст для текста функции или какого-ни слова из кода программы ?

Вот правда, еще остается непонятной роль AO - вроде как и нни к чему он , да еще какой-то непонятныйц остается спец объект из Вашей ссылки выше.

Цитата:
При return d; остаётся ссылка на [[Scope]](d), поэтому все VO в цепи, стоящие иерархически выше - остаются в памяти
Хотел уточнить :
- именно на [[Scope]] , т.е. БЕЗ VO функции d ?
- и сохраняются не просто , если возвращается return, как в Вашем примере b() , а если возвращаемое где-то сохранено var q=b() ?
Ответить с цитированием
  #49 (permalink)  
Старый 15.04.2009, 21:43
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от kefi
И как это все Вы поняли из ECMA спецификации , ума не приложу ...
Несомненно, стоит отметить этого человека - изначально, он помог мне поднять некоторые глубокие аспекты ("Этот человек", только ни в коем случае не считай это за лесть =) я просто благодарен и отдаю должное ). Углубляясь, изучая, дальше сам уже стандарт проштудировал (что и всем советую для профессионального понимания JavaScript).

Сообщение от kefi
Кстати контекст, как я сейчас понимаю, не является термином обозначающим некий объект, это чисто лексический контекст для текста функции или какого-ни слова из кода программы ?
Да, это абстракное определение, зависящее от типа кода: Global code, Eval code, Function code.

Сообщение от kefi
Вот правда, еще остается непонятной роль AO - вроде как и нни к чему он
AO - это и есть VO. А VO, в свою очередь, можно тоже считать абстракцией. Физически же, эта абстракция представлена AO (для функции и eval'a) и Global - для Global'a. У Global'a нет arguments, поэтому для функции это назвали AO. Если говорить отстраннённо от JS, можно представить VO - как интерфейс, а AO и Global - как конкретные классы, реализующие этот интерфейс.

Сообщение от kefi
да еще какой-то непонятныйц остается спец объект
Спец.объект - "анонимный объект", который содержит одно единственное свойство - опциональное имя FE, чтобы FE могла обратиться к себе рекрсивно по имени (помимо arguments.callee):

(function fn() {alert(fn);})();


Откуда alert(fn) выдаёт правильное значение, если FE не воздействуют на VO? Идентификатор fn не должен был попасть в VO(Global). Где же FE его находит? Специально для этого перед созданием FE создаётся этот спец. объект и кладётся в scope chain (в данном случае Global):

Scope(Global).{}.fn = <reference to FE "fn">


Дальше, когда создалась FE "fn", этот спец. объект удаляется из Scope(Global) - теперь он есть в [[Scope]](fn) и, соотвественно, может быть найден.

Здесь ещё можно почитать.

Сообщение от kefi
- именно на [[Scope]] , т.е. БЕЗ VO функции d ?
update: VO и Scope создаются каждый раз при вызове функции; запоминается только [[Scope]](d).

Сообщение от kefi
- и сохраняются не просто , если возвращается return, как в Вашем примере b() , а если возвращаемое где-то сохранено var q=b()
Да, конечно, это тоже подразумевалось.
__________________
Тонкости ECMAScript

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

Цитата:
Конечно же с VO.
Чьим VO? я-то имел ввиду, что VO(d) не сохраняется поскольку НЕ НУЖЕН , т.к. при очередном вызове через замыкание он создается заново .
Ответить с цитированием
Ответ



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

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