Стандарт ECMA-262 (JavaScript) в картинках

enter image description here

Про пристрій JavaScript написано багато статей. В першу чергу, це "JavaScript. Ядро." Дмитра Сошнікова, переклад статті Річарда Корнфорда і докладний пост від компанії Хекслет. Але для того щоб добре розібратися в якій-небудь технології краще звернутися до першоджерел. В даному випадку до стандарту ECMA-262 ECMAScript® Language Specification. Я розглядаю цей пост як полегшений спосіб почати вивчення стандарту. Рекомендую переходити за посиланнями, вчитуватися в текст специфікації і складати власні схеми.

Як працюють замикання в JavaScript
Основні структури ECMAScript це execution context, lexical environment і environment record. Вони пов'язані таким чином:



Крім VariableEnvironment execution context є ще LexicalEnvironment, докладніше про відмінності можна прочитати в ECMAScript 5 spec: LexicalEnvironment versus VariableEnvironment.
ThisBinding буде розглянуто в наступній частині статті
environment record зберігаються значення змінних. Якщо оголосити
var a = 1
, то в поточному record з'явиться {a: 1}. lexical environment крім record є ще поле outer. Outer посилається на зовнішній lexical environment, наприклад, у випадку вкладених функцій.

Пошук змінних починається з VariableEnvironment контексту. Якщо змінна з таким ім'ям не знайдено record, то вона шукається outer environment по ланцюжку.

При запуску програми створюються глобальні context і environment. Як record використовується global object.



Коли інтерпретатор зустрічає ключове слово function створює FunctionObject. Властивості scope створеного FunctionObject записується посилання на поточний lexical environment.

Запис
function f(){}
практично еквівалентна запису
var f = function(){}
за винятком того, що в першому випадку FunctionObject буде створено при вході в блок, що містить
function f()
, а в другому при виконанні конкретної рядки.



При кожному виклику функції створюються нові context, environment і record. Контекст кладе в стек, при виході з функції він знищується. outer створеного environment записується scope викликається FunctionObject. Якщо функція була оголошена в глобальному контексті, то outer буде вказувати на global environment.



Тепер розглянемо замикання, коли одна функція повертає іншу.

var x = 1;

function f() {
var x = 2;
function g() {
return x;
}
return g;
}

f()();

При виклику функції f створюється context і environment f, а також FunctionObject
function g
. scope записується посилання на поточний environment VariableEnvironment. При виході з f контекст знищується, але environment залишиться, так як на нього є посилання з повернутого FunctionObject.



При виклику поверненої з f g створюється контекст і environment g. outer нового environment записується scope з викликається FunctionObject. Пошук змінної x починається з поточного VariableEnvironment і потім продовжується outer. В результаті буде повернено значення
x = 2
.



У наступній частині статті розберемо як з точки зору ECMAScript працює this.

Джерело: Хабрахабр
  • avatar
  • 0

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.