Объекты функций ECMAScript инкапсулируют (encapsulate) параметризованный код ECMAScript, закрытый в лексической среде (lexical environment), и поддерживают динамическую оценку этого кода. Функциональный объект ECMAScript является обычным объектом и имеет те же внутренние слоты и те же внутренние методы, что и другие обычные объекты. Код объекта функции ECMAScript может быть кодом строгого режима (strict mode code)(11.2.2) или нестрогим кодом (non-strict code). Функциональный объект ECMAScript, код которого является кодом строгого режима, называется строгой функцией (strict function). Функция, код которой не является кодом строгого режима, называется нестрогой функцией (non-strict function).
В дополнение к [[Extensible]] и [[Prototype]], объекты функций ECMAScript также имеют внутренние слоты, перечисленные в Таблице 30.
Internal Slot (Внутренний слот) | Type (Тип) | Description (Описание) |
---|---|---|
[[Environment]] | Environment Record | Запись Окружающей Среды о том, что функция была закрыта. Используется как внешняя среда при оценке кода функции. |
[[FormalParameters]] | Parse Node | Корневой узел синтаксического анализа исходного текста, который определяет список формальных параметров функции. |
[[ECMAScriptCode]] | Parse Node | Корневой узел синтаксического анализа исходного текста, определяющий тело функции. |
[[ConstructorKind]] | base | derived | Независимо от того, является ли функция конструктором производного класса. |
[[Realm]] | Realm Record | Область, в которой была создана функция, и которая предоставляет любые внутренние объекты, к которым осуществляется доступ при оценке функции. |
[[ScriptOrModule]] | Script Record или Module Record | Скрипт или модуль, в котором была создана функция. |
[[ThisMode]] | lexical | strict | global | Определяет, как ссылки this интерпретируются в формальных параметрах и теле кода функции. lexical означает, что this относится к значению this как к лексически включающей функции.
strict означает, что значение this используется в точности так, как это предусмотрено при вызове функции. global означает, что значение this, равное «undefined» или «null«, интерпретируется как ссылка на глобальный объект, а любое другое значение this сначала передается в ToObject. |
[[Strict]] | Boolean | true, если это строгая функция, false, если это нестрогая функция. |
[[HomeObject]] | Object | Если функция использует super, это тот объект, [[GetPrototypeOf]] которого предоставляет объект, с которого начинается поиск свойства super. |
[[SourceText]] | последовательность кодовых точек Unicode | Исходный текст, определяющий функцию. |
[[IsClassConstructor]] | Boolean | Указывает, является ли функция конструктором класса. (Если это правда (true), вызов функции [[Call]] немедленно вызовет исключение TypeError.) |
Таблица 30: Внутренние слоты объектов функций ECMAScript
Для всех объектов функций ECMAScript здесь определен внутренний метод [[Call]]. Функции ECMAScript, которые также являются конструкторами, дополнительно имеют внутренний метод [[Construct]].
[[Call]] ( thisArgument, argumentsList )
[[Construct]] ( argumentsList, newTarget )
OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, Scope )
AddRestrictedFunctionProperties ( F, realm )
MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )
MakeClassConstructor ( F )
MakeMethod ( F, homeObject )
SetFunctionName ( F, name [ , prefix ] )
SetFunctionLength ( F, length )
FunctionDeclarationInstantiation ( func, argumentsList )
[[Call]] ( thisArgument, argumentsList )
Внутренний метод [[Call]] объекта функции ECMAScript F принимает аргументы thisArgument (значение языка ECMAScript) и argumentsList (список значений языка ECMAScript). При вызове он выполняет следующие шаги:
1. Утверждено: F - это объект функции ECMAScript. 2. Пусть callerContext будет текущим контекстом выполнения. 3. Пусть calleeContext будет PrepareForOrdinaryCall(F, undefined). 4. Утверждено: calleeContext теперь является текущим контекстом выполнения. 5. Если F.[[IsClassConstructor]] является true, то a. Пусть error будет только что созданным объектом TypeError. b. ПРИМЕЧАНИЕ: ошибка error создается в calleeContext со связанной записью Realm Record F. c. Удалите calleeContext из стека контекста выполнения и восстановите callerContext в качестве текущего контекста выполнения. d. Вернуть ThrowCompletion(error). 6. Выполните OrdinaryCallBindThis(F, calleeContext, thisArgument). 7. Пусть результатом будет OrdinaryCallEvaluateBody(F, argumentsList). 8. Удалите calleeContext из стека контекста выполнения и восстановите callerContext в качестве текущего контекста выполнения. 9. Если result.[[Type]] является return, вернуть Нормальное завершение (result.[[Value]]). 10. ReturnIfAbrupt(result). 11. Вернуть NormalCompletion(undefined).
Когда calleeContext удаляется из стека контекста выполнения на шаге 8, он не должен быть уничтожен, если он приостановлен, и сохранен для последующего возобновления доступным объектом-генератором.
PrepareForOrdinaryCall ( F, newTarget )
Абстрактная операция PrepareForOrdinaryCall (Подготовка для вызова обычного) принимает аргументы F (объект функции) и newTarget (значение языка ECMAScript). При вызове она выполняет следующие шаги:
1. Утверждено: Тип(newTarget) - Не определен (Undefined) или Объект (Object). 2. Пусть callerContext будет текущим контекстом выполнения. 3. Пусть calleeContext будет новым контекстом выполнения кода ECMAScript. 4. Установите для функции calleeContext значение F. 5. Пусть calleeRealm будет F.[[Realm]]. 6. Установите для области calleeContext значение calleeRealm. 7. Установите для ScriptOrModule вызываемого контекста calleeContext значение F.[[ScriptOrModule]]. 8. Пусть localEnv будет NewFunctionEnvironment(F, newTarget). 9. Установите для LexicalEnvironment вызываемого контекста calleeContext значение localEnv. 10. Установите для VariableEnvironment calleeContext значение localEnv. 11. Если callerContext еще не приостановлен, приостановите callerContext. 12. Поместите calleeContext в стек контекста выполнения; calleeContext теперь является текущим контекстом выполнения. 13. ПРИМЕЧАНИЕ. Любые объекты исключения, созданные после этого момента, связаны с calleeRealm. 14. Верните calleeContext.
OrdinaryCallBindThis ( F, calleeContext, thisArgument )
Абстрактная операция OrdinaryCallBindThis (Привязка обычного вызова к this) принимает аргументы F (объект функции), calleeContext (контекст выполнения) и thisArgument (значение языка ECMAScript). При вызове он выполняет следующие шаги:
1. Пусть thisMode будет F.[[ThisMode]]. 2. Если thisMode является "lexical" (лексическим), вернуть NormalCompletion(undefined). 3. Пусть calleeRealm будет F.[[Realm]]. 4. Пусть localEnv будет лексическим окружением (LexicalEnvironment) вызываемого контекста calleeContext. 5. Если thisMode является "strict" (строгим), пусть thisValue будет thisArgument. 6. Иначе, a. Если thisArgument является undefined(не определен) или null, то i. Пусть globalEnv будет calleeRealm.[[GlobalEnv]]. ii. Утверждено: globalEnv - это глобальная запись среды. iii. Пусть thisValue будет globalEnv.[[GlobalThisValue]]. b. Иначе, i. Пусть thisValue будет ! ToObject(thisArgument). ii. ПРИМЕЧАНИЕ. ToObject создает объекты-оболочки с помощью calleeRealm. 7. Утверждено: localEnv - это функциональная запись среды. 8. Утверждено: следующий шаг никогда не возвращает внезапное завершение, потому что localEnv.[[ThisBindingStatus]] не является "initialized". 9. Верните localEnv.BindThisValue(thisValue).
Семантика среды выполнения: EvaluateBody
С параметрами functionObject и argumentsList (Список).
FunctionBody : FunctionStatementList
1. Вернуть ? EvaluateFunctionBody для FunctionBody с аргументами functionObject и argumentsList.
1. Вернуть ? EvaluateConciseBody из ConciseBody с аргументами functionObject и argumentsList.
1. Вернуть ? EvaluateGeneratorBody объекта GeneratorBody с аргументами functionObject и argumentsList.
AsyncGeneratorBody : FunctionBody
1. Вернуть ? EvaluateAsyncGeneratorBody из AsyncGeneratorBody с аргументами functionObject и argumentsList.
AsyncFunctionBody : FunctionBody
1. Вернуть ? EvaluateAsyncFunctionBody для AsyncFunctionBody с аргументами functionObject и argumentsList.
AsyncConciseBody : ExpressionBody
1. Вернуть ? EvaluateAsyncConciseBody из AsyncConciseBody с аргументами functionObject и argumentsList.
OrdinaryCallEvaluateBody ( F, argumentsList )
Абстрактная операция OrdinaryCallEvaluateBody (Обычный вызов оценки тела) принимает аргументы F (объект функции) и argumentsList (Список). При вызове она выполняет следующие шаги:
1. Верните результат оценки тела EvaluateBody проанализированного кода, то есть F.[[ECMAScriptCode]], передав F и argumentsList в качестве аргументов.
[[Construct]] ( argumentsList, newTarget )
Внутренний метод [[Construct]] объекта функции ECMAScript F принимает аргументы argumentsList (список значений языка ECMAScript) и newTarget (конструктор). При вызове он выполняет следующие шаги:
1. Утверждено: F - объект функции ECMAScript. 2. Утверждено: Тип(newTarget) - это объект. 3. Пусть callerContext будет текущим контекстом выполнения. 4. Пусть kind будет F.[[ConstructorKind]]. 5. Если kind является "base"(базовым), то a. Пусть thisArgument будет ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%"). 6. Пусть calleeContext будет PrepareForOrdinaryCall(F, newTarget). 7. Утверждено: calleeContext теперь является текущим контекстом выполнения. 8. Если kind является "base"(базовым), выполните OrdinaryCallBindThis(F, calleeContext, thisArgument). 9. Пусть constructorEnv будет LexicalEnvironment для calleeContext. 10. Пусть result будет OrdinaryCallEvaluateBody(F, argumentsList). 11. Удалите calleeContext из стека контекста выполнения и восстановите callerContext как текущий контекст выполнения. 12. Если result.[[Type]] является "return", тогда a. Если Type(result.[[Value]]) - это Объект, вернуть NormalCompletion(result.[[Value]]). b. Если kind является "base"(базовым), вернуть NormalCompletion(thisArgument). c. Если result.[[Value]] не является undefined, выбросить исключение TypeError. 13. Иначе, ReturnIfAbrupt(result). 14. Вернуть ? constructorEnv.GetThisBinding().
OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, Scope )
Абстрактная операция OrdinaryFunctionCreate (Создание обычной функции) принимает аргументы functionPrototype (объект), sourceText (последовательность кодовых точек Unicode), ParameterList (узел синтаксического анализа), Body (узел синтаксического анализа), thisMode («lexical-this» лексический-this или «non-lexical-this» нелексический-this), и Scope (запись среды). sourceText — это исходный текст синтаксического определения создаваемой функции. При вызове он выполняет следующие шаги:
1. Утверждено: Тип(functionPrototype) - это объект. 2. Пусть internalSlotsList будет внутренними слотами, перечисленными в Таблице 30. 3. Пусть F будет ! OrdinaryObjectCreate(functionPrototype, internalSlotsList). 4. Установите F.[[Call]] на определение, указанное в 10.2.1. 5. Установите для F.[[SourceText]] значение sourceText. 6. Установите для F.[[FormalParameters]] значение ParameterList. 7. Установите для F.[[ECMAScriptCode]] значение Body. 8. Если исходный текст, соответствующий Body, является кодом в строгом режиме, пусть Strict будет истинным true; иначе пусть Strict будет ложным false. 9. Установите F.[[Strict]] на Strict. 10. Если thisMode является лексическим-this ("lexical-this"), установите для F.[[ThisMode]] значение ("lexical"). 11. В противном случае, если Strict истинно true, установите F.[[ThisMode]] на строгий ("strict"). 12. В противном случае установите для F.[[ThisMode]] значение глобальный ("global"). 13. Установите для F.[[IsClassConstructor]] значение false. 14. Установите F.[[Environment]] в Scope. 15. Установите для F.[[ScriptOrModule]] значение GetActiveScriptOrModule(). 16. Установите F.[[Realm]] на текущую запись Realm. 17. Установите для F.[[HomeObject]] значение undefined. 18. Пусть len будет ExpectedArgumentCount в ParameterList. 19. Выполнять ! SetFunctionLength(F, len). 20. Вернуть F.
AddRestrictedFunctionProperties ( F, realm )
Абстрактная операция AddRestrictedFunctionProperties (Добавить свойства функции с ограничениями) принимает аргументы F (объект функции) и realm (запись области). При вызове он выполняет следующие шаги:
1. Утверждено: realm.[[Intrinsics]].[[%ThrowTypeError%]] существует и была инициализирована. 2. Пусть метателем thrower будет realm.[[Intrinsics]].[[%ThrowTypeError%]]. 3. Выполнять ! DefinePropertyOrThrow(F, "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true} ». 4. Вернитесь ! DefinePropertyOrThrow(F, "arguments", PropertyDescriptor {[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true} »).
%ThrowTypeError% ( )
Внутренний объект %ThrowTypeError% — это анонимный встроенный функциональный объект, который определяется один раз для каждой области. Когда вызывается %ThrowTypeError%, он выполняет следующие шаги:
1. Вызвать исключение TypeError.
Значение внутреннего слота [[Extensible]] функции %ThrowTypeError% равно false.
Свойство «length» функции %ThrowTypeError% имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}.
Свойство «name» функции %ThrowTypeError% имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}.
MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )
Абстрактная операция MakeConstructor (Сделать конструктор) принимает аргумент F (объект функции) и необязательные аргументы writablePrototype (логическое значение) и prototype (объект). Он преобразует F в конструктор. При вызове он выполняет следующие шаги:
1. Утверждено: F - объект функции ECMAScript или встроенный объект функции. 2. Если F является объектом функции ECMAScript, тогда a. Утверждено: IsConstructor(F) ложно false. b. Утверждено: F - расширяемый объект, не имеющий собственного свойства "prototype". c. Установите F.[[Construct]] на определение, указанное в 10.2.2. 3. Установите для F.[[ConstructorKind]] значение "base". 4. Если writablePrototype не указан, установите для параметра writablePrototype значение true. 5. Если прототипа prototype нет, то a. Установите prototype на ! OrdinaryObjectCreate(%Object.prototype%). b. Выполнять ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true }). 6. Выполнять ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false }). 7. Вернуть NormalCompletion(undefined).
MakeClassConstructor ( F )
Абстрактная операция MakeClassConstructor (Сделать конструктор классов) принимает аргумент F. При вызове она выполняет следующие шаги:
1. Утверждено: F - это объект функции ECMAScript. 2. Утверждено: F.[[IsClassConstructor]] ложно false. 3. Установите для F.[[IsClassConstructor]] значение true. 4. Вернуть NormalCompletion(undefined).
MakeMethod ( F, homeObject )
Абстрактная операция MakeMethod (Сделать метод) принимает аргументы F и homeObject. Она настраивает F как метод. При вызове он выполняет следующие шаги:
1. Утверждено: F - это объект функции ECMAScript. 2. Утверждено: Тип(homeObject) - это Объект. 3. Установите для F.[[HomeObject]] значение homeObject. 4. Вернуть NormalCompletion(undefined).
SetFunctionName ( F, name [ , prefix ] )
Абстрактная операция SetFunctionName (Установить название функции) принимает аргументы F (объект функции) и name (ключ свойства) и необязательный аргумент prefix (String). Она добавляет свойство «name» к F. При вызове она выполняет следующие шаги:
1. Утверждено: F - это расширяемый объект, не имеющий собственного свойства "name". 2. Утверждено: Тип(name) - либо Символ, либо Строка. 3. Утверждено: если префикс prefix присутствует, то Тип(prefix) - это Строка. 4. Если Тип(name) является Символ, тогда a. Пусть описание description будет значением [[Description]] имени name. b. Если описание description является undefined, установите имя name в пустую Строку. c. В противном случае задайте имя name для конкатенации строк из "[", description, и "]". 5. Если F имеет внутренний слот [[InitialName]], то a. Установите для name значение F.[[InitialName]]. 6. Если префикс prefix присутствует, то a. Задайте для имени name конкатенацию строк из префикса prefix, единицы кода 0x0020 (ПРОБЕЛ) и name. b. Если F имеет внутренний слот [[InitialName]], то i. При желании задайте F.[[InitialName]] для имени name. 7. Вернуть ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
SetFunctionLength ( F, length )
Абстрактная операция SetFunctionLength (Установить длину функции) принимает аргументы F (объект функции) и длину length (неотрицательное целое число или +∞). Она добавляет свойство «length» к F. При вызове он выполняет следующие шаги:
1. Утверждено: F - это расширяемый объект, не имеющий собственного свойства "length". 2. Вернуть ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
FunctionDeclarationInstantiation ( func, argumentsList )
Когда контекст выполнения устанавливается для оценки функции ECMAScript, создается новая запись среды функции, и в этой записи среды создаются привязки для каждого формального параметра. Также создается каждое объявление в теле функции. Если формальные параметры функции не включают инициализаторы значений по умолчанию, тогда объявления тела создаются в той же записи среды, что и параметры. Если существуют инициализаторы параметров значения по умолчанию, для объявлений тела создается вторая запись среды. Формальные параметры и функции инициализируются как часть FunctionDeclarationInstantiation (Создание экземпляра объявления функции). Все остальные привязки инициализируются во время оценки тела функции.
Абстрактная операция FunctionDeclarationInstantiation (Создание экземпляра объявления функции) принимает аргументы func (объект функции) и argumentsList. func — это объект функции, для которого устанавливается контекст выполнения. При вызове он выполняет следующие шаги:
1. Пусть calleeContext будет текущим контекстом выполнения. 2. Пусть код code будет func.[[ECMAScriptCode]]. 3. Пусть strict будет func.[[Strict]]. 4. Пусть formals будет func.[[FormalParameters]]. 5. Пусть parameterNames будет BoundNames formals. 6. Если в parameterNames есть какие-либо повторяющиеся записи, пусть hasDuplicates имеет значение true. В противном случае пусть hasDuplicates будет false. 7. Пусть simpleParameterList будет IsSimpleParameterList из formals. 8. Пусть hasParameterExpressions будет ContainsExpression из formals. 9. Пусть varNames будет VarDeclaredNames из кода code. 10. Пусть varDeclarations будет VarScopedDeclarations из кода code. 11. Пусть lexicalNames будет LexicallyDeclaredNames из кода code. 12. Пусть functionNames будет новым пустым списком. 13. Пусть functionsToInitialize будет новым пустым списком. 14. Для каждого элемента d из varDeclarations в обратном порядке списка выполните а. Если d не является ни VariableDeclaration, ни ForBinding, ни BindingIdentifier, тогда i. Утверждено: d - это либо FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, либо AsyncGeneratorDeclaration. ii. Пусть fn будет единственным элементом BoundNames из d. iii. Если fn не является элементом functionNames, тогда 1. Вставьте fn как первый элемент functionNames. 2. ПРИМЕЧАНИЕ. Если существует несколько объявлений функций для одного и того же имени, используется последнее объявление. 3. Вставьте d как первый элемент functionsToInitialize. 15. Пусть argumentsObjectNeeded имеет значение true. 16. Если func.[[ThisMode]] является "lexical" (лексический), то a. ПРИМЕЧАНИЕ. Стрелочные функции никогда не имеют объектов аргументов. b. Установите argumentsObjectNeeded в false. 17. Иначе, если "arguments" является элементом parameterNames, тогда a. Установите argumentsObjectNeeded в значение false. 18. Иначе, если hasParameterExpressions является false (ложно), то a. Если "arguments" является элементом functionNames или если "arguments" является элементом lexicalNames, тогда i. Установите argumentsObjectNeeded в значение false. 19. Если strict является true (истинно) или hasParameterExpressions имеет значение false, тогда a. ПРИМЕЧАНИЕ. Для параметров и переменных верхнего уровня требуется только одна запись среды. b. Пусть env будет LexicalEnvironment для calleeContext. 20. Иначе, a. ПРИМЕЧАНИЕ. Необходима отдельная запись среды, чтобы гарантировать, что привязки, созданные прямыми вызовами eval в списке формальных параметров, находятся за пределами среды, в которой объявлены параметры. b. Пусть calleeEnv будет LexicalEnvironment для calleeContext. c. Пусть env будет NewDeclarativeEnvironment(calleeEnv). d. Утверждено: VariableEnvironment для calleeContext - это calleeEnv. e. Установите для LexicalEnvironment calleeContext значение env. 21. Для каждой строки paramName из parameterNames выполните а. Пусть alreadyDeclared будет env.HasBinding(paramName). b. ПРИМЕЧАНИЕ. Ранние ошибки гарантируют, что повторяющиеся имена параметров могут возникать только в нестрогих функциях, которые не имеют значений параметров по умолчанию или остальных параметров. c. Если alreadyDeclared является false(ложно), то i. Выполнить ! env.CreateMutableBinding(paramName, false). ii. Если hasDuplicates является true(истинно), то 1. Выполнить! env.InitializeBinding(paramName, undefined). 22. Если argumentsObjectNeeded имеет значение true, тогда а. Если strict является true(истинно) или если simpleParameterList является false(ложно), то i. Пусть ao будет CreateUnmappedArgumentsObject(argumentsList). b. Еще, i. ПРИМЕЧАНИЕ. Отображенный объект аргумента предоставляется только для нестрогих функций, у которых нет параметра rest, каких-либо инициализаторов значений параметров по умолчанию или любых деструктурированных параметров. ii. Пусть ao будет CreateMappedArgumentsObject(func, formals, argumentsList, env). c. Если strict является true(истинно), то i. Выполнять ! env.CreateImmutableBinding("arguments", false). d. Еще, i. Выполнять ! env.CreateMutableBinding("arguments", false). е. Вызовите env.InitializeBinding ("arguments", ao). f. Пусть parameterBindings будет List, элементы которого являются элементами parameterNames, за которыми следуют "arguments". 23. Иначе, а. Пусть parameterBindings будет parameterNames. 24. Пусть iteratorRecord будет CreateListIteratorRecord(argumentsList). 25. Если hasDuplicates является true(истинно), то а. Выполнить ? IteratorBindingInitialization для formals с iteratorRecord и undefined в качестве аргументов. 26. Иначе, а. Выполнить ? IteratorBindingInitialization для formals с iteratorRecord и env в качестве аргументов. 27. Если hasParameterExpressions является false(ложно), то а. ПРИМЕЧАНИЕ. Для параметров и переменных верхнего уровня требуется только одна запись среды. b. Пусть instantiatedVarNames будет копией List parameterBindings. c. Для каждого элемента n из varNames выполните i. Если n не является элементом instantiatedVarNames, тогда 1. Добавьте n к instantiatedVarNames. 2. Выполните ! env.CreateMutableBinding(n, false). 3. Вызовите env.InitializeBinding(n, undefined). d. Пусть varEnv будет env. 28. Иначе, а. ПРИМЕЧАНИЕ. Необходима отдельная запись среды, чтобы гарантировать, что замыкания, созданные выражениями в списке формальных параметров, не имеют видимости объявлений в теле функции. b. Пусть varEnv будет NewDeclarativeEnvironment(env). c. Установите для VariableEnvironment calleeContext значение varEnv. d. Пусть instantiatedVarNames будет новым пустым Списком. е. Для каждого элемента n из varNames выполните i. Если n не является элементом instantiatedVarNames, тогда 1. Добавьте n к instantiatedVarNames. 2. Выполнить ! varEnv.CreateMutableBinding(n, false). 3. Если n не является элементом parameterBindings или если n является элементом functionNames, пусть initialValue будет undefined. 4. Иначе, а. Пусть initialValue будет ! env.GetBindingValue(n, false). 5. Вызовите varEnv.InitializeBinding(n, initialValue). 6. ПРИМЕЧАНИЕ. Переменная с тем же именем, что и формальный параметр, изначально имеет то же значение, что и соответствующий инициализированный параметр. 29. ПРИМЕЧАНИЕ. В Приложении B.3.3.1 на этом этапе добавлены дополнительные шаги. 30. Если strict является false, то a. Пусть lexEnv будет NewDeclarativeEnvironment(varEnv). b. ПРИМЕЧАНИЕ. Нестрогие функции используют отдельную запись среды для лексических объявлений верхнего уровня, так что прямой eval может определить, конфликтуют ли какие-либо объявления с областью действия, введенные кодом eval, с ранее существовавшими объявлениями с лексической областью действия верхнего уровня. Это не требуется для строгих функций, потому что строгое прямое eval всегда помещает все объявления в новую запись среды. 31. В противном случае пусть lexEnv будет varEnv. 32. Установите для LexicalEnvironment вызываемого контекста calleeContext значение lexEnv. 33. Пусть lexDeclarations будет LexicallyScopedDeclarations из кода code. 34. Для каждого элемента d из lexDeclarations выполните a. ПРИМЕЧАНИЕ. Лексически объявленное имя не может совпадать с объявлением функции/генератора, формальным параметром или именем переменной. Лексически объявленные имена здесь только инстанциируются, но не инициализируются. b. Для каждого элемента dn из BoundNames из d выполните i. Если IsConstantDeclaration из d является true(истинно), то 1. Выполнить ! lexEnv.CreateImmutableBinding(dn, true). ii. Еще, 1. Выполнить ! lexEnv.CreateMutableBinding(dn, false). 35. Для каждого узла синтаксического анализа функции f из functionsToInitialize выполните а. Пусть fn будет единственным элементом из BoundNames функции f. b. Пусть fo будет InstantiateFunctionObject для f с аргументом lexEnv. c. Выполнить ! varEnv.SetMutableBinding (fn, fo, false). 36. Вернуть NormalCompletion(empty).
B.3.3 предоставляет расширение для вышеуказанного алгоритма, которое необходимо для обратной совместимости с реализациями ECMAScript в веб-браузерах, предшествующими ECMAScript 2015.
Инициализаторы (Initializers) параметров могут содержать прямые выражения eval. Любые объявления таких значений верхнего уровня видны только коду eval (11.2). Создание среды для таких объявлений описано в разделе 8.5.3.
Информационные ссылки
Предыдущий раздел «ECMAScript | Внутренние методы и внутренние слоты обычных объектов»
Стандарт ECMAScript — Раздел «ECMAScript Function Objects» — https://tc39.es/ecma262/#sec-ecmascript-function-objects