Исполняемый код и контекст исполнения в JS

Содержание

Слайд 2

В JS нет магии :) var a = 5; function foo()

В JS нет магии :)

var a = 5;
function foo() { console.log(a); }
function

bar() { foo(); console.log(a); var a = 6; }
bar();
Слайд 3

Область видимости var x = 10; function foo() { console.log(x); }

Область видимости

var x = 10;
function foo() { console.log(x); }
foo(); // 10
function bar()

{ var x = 20; console.log(x); // 20 foo(); // 10 } bar();

x = 10;
procedure foo() print(x) end
foo() // 10
procedure bar() x = 20 foo() // 20 end
bar()

Статическая область видимости:

Динамическая область видимости:

Слайд 4

Лексическая область видимости Спецификация, используемая для определения связи идентификаторов с конкретными

Лексическая область видимости

Спецификация, используемая для определения связи идентификаторов с конкретными значениями

и функциями;
Связано с синтаксической структурой кода, такой как FunctionDeclaration, BlockStatement, Catch и TryStatement;
Состоит из записи окружения и ссылки на внешнее лексическое окружение;
Слайд 5

Пример: var x = 10; function foo() { var y =

Пример:

var x = 10;
function foo() {
var y = 20;
}

globalEnvironment =

{
environmentRecord: {
Object: function,
// etc ...
x: 10
},
outer: null
};
fooEnvironment = {
environmentRecord: {
y: 20
},
outer: globalEnvironment
};
Слайд 6

Пример: function foo() { var x = 10; function bar() {

Пример:

function foo() {
var x = 10;
function bar() {
var

y = 20;
console.log(x + y); // 30
}
function baz() {
var z = 30;
console.log(x + y); // 40
}
}

fooEnvironment = {
environmentRecord: {x: 10},
outer: globalEnvironment
};
barEnvironment = {
environmentRecord: {y: 20},
outer: fooEnvironment
};
bazEnvironment = {
environmentRecord: {z: 30},
outer: fooEnvironment
};

Слайд 7

Типы записей окружения Декларативные записи Каждая декларативная запись среды связана с

Типы записей окружения

Декларативные записи
Каждая декларативная запись среды связана с областью программы

ECMAScript, содержащей объявления переменных, констант, let, class, module, import и / или функций. Декларативная запись среды связывает набор идентификаторов, определенных объявлениями, содержащимися в его области.)
Объектные записи
Запись объектной среды используется для определения связи переменных и функций, появившихся в глобальном контексте и внутри with-операторов.
Слайд 8

Вид декларативной записи окружения function foo(a) { var b = 10;

Вид декларативной записи окружения

function foo(a) {
var b = 10;
function

c() {}
}

environment = {
// storage
environmentRecord: {
type: "declarative",
a: <...>,
b: <...>,
c: <...>
},
// reference to the parent environment
outer: <...>
};

Слайд 9

Пример объектной записи окружения var a = 10; var b =

Пример объектной записи окружения

var a = 10;
var b = 20;
with ({a:

30}) {
console.log(a + b); // 50
}
console.log(a + b); // 30, restored

context.lexicalEnv = {
environmentRecord: {a: 10, b: 20},
outer: null
};
previousEnv = context.lexicalEnv;
withEnv = {
environmentRecord: {a: 30},
outer: context.lexicalEnv
};
context.lexicalEnv = withEnv;
context.lexicalEnv = previousEnv;

Слайд 10

Контекст исполнения This Переменные компоненты среды Лексические компоненты среды ExecutionContext =

Контекст исполнения

This
Переменные компоненты среды
Лексические компоненты среды

ExecutionContext = {
ThisBinding: ,

VariableEnvironment: { ... },
LexicalEnvironment: { ... },
}
Слайд 11

This В глобальном контексте this - глобальный объект Внутри контекста функции

This

В глобальном контексте this - глобальный объект
Внутри контекста функции this определяется

формой вызова функции

var foo = {
bar: function () {
console.log(this);
};
};

foo.bar();// "this" === "foo"
var bar = foo.bar;
bar();// "this" === global
this.bar();// "this" === global
bar.prototype.constructor();// "this" === "bar.prototype"
// --- non-Reference cases ---
(foo.bar = foo.bar)();// "this" === "global" or "undefined"
(foo.bar || foo.bar)();// "this" === "global" or "undefined"
(function () {this;})();//"this" === "global" || "undefined"

Слайд 12

Переменные компоненты среды function foo(a) { var b = 20; }

Переменные компоненты среды

function foo(a) {
var b = 20;
}
foo(10);

fooContext.VariableEnvironment = {

environmentRecord: {
arguments: {0: 10, length: 1, callee: foo},
a: 10,
b: 20
},
outer: globalEnvironment
};
Слайд 13

Лексические компоненты среды var a = 10; function foo() {console.log(a);} with

Лексические компоненты среды

var a = 10;
function foo() {console.log(a);}
with ({a: 20}) {

var bar = function () {
console.log(a);
};
foo(); // 10, from VariableEnv
bar(); // 20, from LexicalEnv
}
foo(); // 10
bar(); // still 20

foo.[[Scope]] = globalContext.[[VariableEnvironment]];
// "with"
previousEnvironment = globalContext.[[LexicalEnvironment]];
globalContext.[[LexicalEnvironment]] = {
environmentRecord: {a: 20},
outer: previousEnvironment
};
// "bar" is created
bar.[[Scope]] = globalContext.[[LexicalEnvironment]];
// "with" is completed, restore the environment
globalContext.[[LexicalEnvironment]] = previousEnvironment;

Слайд 14

Инициализация идентификаторов Процесс определения значения идентификатора, появившегося в контексте, с использованием

Инициализация идентификаторов

Процесс определения значения идентификатора, появившегося в контексте, с использованием лексического

компонента в текущем контексте выполнения

function resolveIdentifier(lexicalEnvironment, identifier) {
// если метод вызван из конечного окружения, переменной нет
if (lexicalEnvironment == null) {
throw ReferenceError(identifier + " is not defined");
}
// если значение найдено, возвращаем его Reference
if (lexicalEnvironment.hasBinding(identifier)) {
return new Reference(lexicalEnvironment, identifier);
}
return resolveIdentifier(lexicalEnvironment.outer, identifier);
}

Слайд 15

Пример var a = 10; (function foo() { var b =

Пример

var a = 10;
(function foo() {
var b = 20;
(function bar()

{
var c = 30;
console.log(a + b + c); // 60
})();
})();

resolveIdentifier(bar.[[LexicalEnvironment]], "a") ->
-- bar.[[LexicalEnvironment]] - not found,
-- bar.[[LexicalEnvironment]].outer ->
foo.[[LexicalEnvironment]]) -> not found
-- bar.[[LexicalEnvironment]].outer.outer ->
found reference, value 10