ECMAScript® 2024 Language Specification

Draft ECMA-262 / February 15, 2024

10.2 ECMAScript Function Objects

ECMAScript function objects encapsulate parameterized ECMAScript code closed over a lexical environment and support the dynamic evaluation of that code. An ECMAScript function object is an ordinary object and has the same internal slots and the same internal methods as other ordinary objects. The code of an ECMAScript function object may be either strict mode code (11.2.2) or non-strict code. An ECMAScript function object whose code is strict mode code is called a strict function. One whose code is not strict mode code is called a non-strict function.

In addition to [[Extensible]] and [[Prototype]], ECMAScript function objects also have the internal slots listed in Table 30.

Table 30: Internal Slots of ECMAScript Function Objects
Internal Slot Type Description
[[Environment]] an Environment Record The Environment Record that the function was closed over. Used as the outer environment when evaluating the code of the function.
[[PrivateEnvironment]] a PrivateEnvironment Record or null The PrivateEnvironment Record for Private Names that the function was closed over. null if this function is not syntactically contained within a class. Used as the outer PrivateEnvironment for inner classes when evaluating the code of the function.
[[FormalParameters]] a Parse Node The root parse node of the source text that defines the function's formal parameter list.
[[ECMAScriptCode]] a Parse Node The root parse node of the source text that defines the function's body.
[[ConstructorKind]] base or derived Whether or not the function is a derived class constructor.
[[Realm]] a Realm Record The realm in which the function was created and which provides any intrinsic objects that are accessed when evaluating the function.
[[ScriptOrModule]] a Script Record or a Module Record The script or module in which the function was created.
[[ThisMode]] lexical, strict, or global Defines how this references are interpreted within the formal parameters and code body of the function. lexical means that this refers to the this value of a lexically enclosing function. strict means that the this value is used exactly as provided by an invocation of the function. global means that a this value of undefined or null is interpreted as a reference to the global object, and any other this value is first passed to ToObject.
[[Strict]] a Boolean true if this is a strict function, false if this is a non-strict function.
[[HomeObject]] an Object If the function uses super, this is the object whose [[GetPrototypeOf]] provides the object where super property lookups begin.
[[SourceText]] a sequence of Unicode code points The source text that defines the function.
[[Fields]] a List of ClassFieldDefinition Records If the function is a class, this is a list of Records representing the non-static fields and corresponding initializers of the class.
[[PrivateMethods]] a List of PrivateElements If the function is a class, this is a list representing the non-static private methods and accessors of the class.
[[ClassFieldInitializerName]] a String, a Symbol, a Private Name, or empty If the function is created as the initializer of a class field, the name to use for NamedEvaluation of the field; empty otherwise.
[[IsClassConstructor]] a Boolean Indicates whether the function is a class constructor. (If true, invoking the function's [[Call]] will immediately throw a TypeError exception.)

All ECMAScript function objects have the [[Call]] internal method defined here. ECMAScript functions that are also constructors in addition have the [[Construct]] internal method.

10.2.1 [[Call]] ( thisArgument, argumentsList )

The [[Call]] internal method of an ECMAScript function object F takes arguments thisArgument (an ECMAScript language value) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let callerContext be the running execution context.
  2. Let calleeContext be PrepareForOrdinaryCall(F, undefined).
  3. Assert: calleeContext is now the running execution context.
  4. If F.[[IsClassConstructor]] is true, then
    1. Let error be a newly created TypeError object.
    2. NOTE: error is created in calleeContext with F's associated Realm Record.
    3. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
    4. Return ThrowCompletion(error).
  5. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
  6. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
  7. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  8. If result is a return completion, return result.[[Value]].
  9. ReturnIfAbrupt(result).
  10. Return undefined.
Note

When calleeContext is removed from the execution context stack in step 7 it must not be destroyed if it is suspended and retained for later resumption by an accessible Generator.

10.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

The abstract operation PrepareForOrdinaryCall takes arguments F (an ECMAScript function object) and newTarget (an Object or undefined) and returns an execution context. It performs the following steps when called:

  1. Let callerContext be the running execution context.
  2. Let calleeContext be a new ECMAScript code execution context.
  3. Set the Function of calleeContext to F.
  4. Let calleeRealm be F.[[Realm]].
  5. Set the Realm of calleeContext to calleeRealm.
  6. Set the ScriptOrModule of calleeContext to F.[[ScriptOrModule]].
  7. Let localEnv be NewFunctionEnvironment(F, newTarget).
  8. Set the LexicalEnvironment of calleeContext to localEnv.
  9. Set the VariableEnvironment of calleeContext to localEnv.
  10. Set the PrivateEnvironment of calleeContext to F.[[PrivateEnvironment]].
  11. If callerContext is not already suspended, suspend callerContext.
  12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  13. NOTE: Any exception objects produced after this point are associated with calleeRealm.
  14. Return calleeContext.

10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

The abstract operation OrdinaryCallBindThis takes arguments F (an ECMAScript function object), calleeContext (an execution context), and thisArgument (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Let thisMode be F.[[ThisMode]].
  2. If thisMode is lexical, return unused.
  3. Let calleeRealm be F.[[Realm]].
  4. Let localEnv be the LexicalEnvironment of calleeContext.
  5. If thisMode is strict, then
    1. Let thisValue be thisArgument.
  6. Else,
    1. If thisArgument is either undefined or null, then
      1. Let globalEnv be calleeRealm.[[GlobalEnv]].
      2. Assert: globalEnv is a Global Environment Record.
      3. Let thisValue be globalEnv.[[GlobalThisValue]].
    2. Else,
      1. Let thisValue be ! ToObject(thisArgument).
      2. NOTE: ToObject produces wrapper objects using calleeRealm.
  7. Assert: localEnv is a Function Environment Record.
  8. Assert: The next step never returns an abrupt completion because localEnv.[[ThisBindingStatus]] is not initialized.
  9. Perform ! localEnv.BindThisValue(thisValue).
  10. Return unused.

10.2.1.3 Runtime Semantics: EvaluateBody

The syntax-directed operation EvaluateBody takes arguments functionObject (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It is defined piecewise over the following productions:

FunctionBody : FunctionStatementList
  1. Return ? EvaluateFunctionBody of FunctionBody with arguments functionObject and argumentsList.
ConciseBody : ExpressionBody
  1. Return ? EvaluateConciseBody of ConciseBody with arguments functionObject and argumentsList.
GeneratorBody : FunctionBody
  1. Return ? EvaluateGeneratorBody of GeneratorBody with arguments functionObject and argumentsList.
AsyncGeneratorBody : FunctionBody
  1. Return ? EvaluateAsyncGeneratorBody of AsyncGeneratorBody with arguments functionObject and argumentsList.
AsyncFunctionBody : FunctionBody
  1. Return ? EvaluateAsyncFunctionBody of AsyncFunctionBody with arguments functionObject and argumentsList.
AsyncConciseBody : ExpressionBody
  1. Return ? EvaluateAsyncConciseBody of AsyncConciseBody with arguments functionObject and argumentsList.
Initializer : = AssignmentExpression
  1. Assert: argumentsList is empty.
  2. Assert: functionObject.[[ClassFieldInitializerName]] is not empty.
  3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let value be ? NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]].
  4. Else,
    1. Let rhs be ? Evaluation of AssignmentExpression.
    2. Let value be ? GetValue(rhs).
  5. Return Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
Note

Even though field initializers constitute a function boundary, calling FunctionDeclarationInstantiation does not have any observable effect and so is omitted.

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Assert: argumentsList is empty.
  2. Return ? EvaluateClassStaticBlockBody of ClassStaticBlockBody with argument functionObject.

10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList )

The abstract operation OrdinaryCallEvaluateBody takes arguments F (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Return ? EvaluateBody of F.[[ECMAScriptCode]] with arguments F and argumentsList.

10.2.2 [[Construct]] ( argumentsList, newTarget )

The [[Construct]] internal method of an ECMAScript function object F takes arguments argumentsList (a List of ECMAScript language values) and newTarget (a constructor) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let callerContext be the running execution context.
  2. Let kind be F.[[ConstructorKind]].
  3. If kind is base, then
    1. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%").
  4. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
  5. Assert: calleeContext is now the running execution context.
  6. If kind is base, then
    1. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
    2. Let initializeResult be Completion(InitializeInstanceElements(thisArgument, F)).
    3. If initializeResult is an abrupt completion, then
      1. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
      2. Return ? initializeResult.
  7. Let constructorEnv be the LexicalEnvironment of calleeContext.
  8. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
  9. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  10. If result is a return completion, then
    1. If result.[[Value]] is an Object, return result.[[Value]].
    2. If kind is base, return thisArgument.
    3. If result.[[Value]] is not undefined, throw a TypeError exception.
  11. Else,
    1. ReturnIfAbrupt(result).
  12. Let thisBinding be ? constructorEnv.GetThisBinding().
  13. Assert: thisBinding is an Object.
  14. Return thisBinding.

10.2.3 OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, env, privateEnv )

The abstract operation OrdinaryFunctionCreate takes arguments functionPrototype (an Object), sourceText (a sequence of Unicode code points), ParameterList (a Parse Node), Body (a Parse Node), thisMode (lexical-this or non-lexical-this), env (an Environment Record), and privateEnv (a PrivateEnvironment Record or null) and returns an ECMAScript function object. It is used to specify the runtime creation of a new function with a default [[Call]] internal method and no [[Construct]] internal method (although one may be subsequently added by an operation such as MakeConstructor). sourceText is the source text of the syntactic definition of the function to be created. It performs the following steps when called:

  1. Let internalSlotsList be the internal slots listed in Table 30.
  2. Let F be OrdinaryObjectCreate(functionPrototype, internalSlotsList).
  3. Set F.[[Call]] to the definition specified in 10.2.1.
  4. Set F.[[SourceText]] to sourceText.
  5. Set F.[[FormalParameters]] to ParameterList.
  6. Set F.[[ECMAScriptCode]] to Body.
  7. If the source text matched by Body is strict mode code, let Strict be true; else let Strict be false.
  8. Set F.[[Strict]] to Strict.
  9. If thisMode is lexical-this, set F.[[ThisMode]] to lexical.
  10. Else if Strict is true, set F.[[ThisMode]] to strict.
  11. Else, set F.[[ThisMode]] to global.
  12. Set F.[[IsClassConstructor]] to false.
  13. Set F.[[Environment]] to env.
  14. Set F.[[PrivateEnvironment]] to privateEnv.
  15. Set F.[[ScriptOrModule]] to GetActiveScriptOrModule().
  16. Set F.[[Realm]] to the current Realm Record.
  17. Set F.[[HomeObject]] to undefined.
  18. Set F.[[Fields]] to a new empty List.
  19. Set F.[[PrivateMethods]] to a new empty List.
  20. Set F.[[ClassFieldInitializerName]] to empty.
  21. Let len be the ExpectedArgumentCount of ParameterList.
  22. Perform SetFunctionLength(F, len).
  23. Return F.

10.2.4 AddRestrictedFunctionProperties ( F, realm )

The abstract operation AddRestrictedFunctionProperties takes arguments F (a function object) and realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. Assert: realm.[[Intrinsics]].[[%ThrowTypeError%]] exists and has been initialized.
  2. Let thrower be realm.[[Intrinsics]].[[%ThrowTypeError%]].
  3. Perform ! DefinePropertyOrThrow(F, "caller", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true }).
  4. Perform ! DefinePropertyOrThrow(F, "arguments", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true }).
  5. Return unused.

10.2.4.1 %ThrowTypeError% ( )

This function is the %ThrowTypeError% intrinsic object.

It is an anonymous built-in function object that is defined once for each realm.

It performs the following steps when called:

  1. Throw a TypeError exception.

The value of the [[Extensible]] internal slot of this function is false.

The "length" property of this function has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

The "name" property of this function has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

10.2.5 MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )

The abstract operation MakeConstructor takes argument F (an ECMAScript function object or a built-in function object) and optional arguments writablePrototype (a Boolean) and prototype (an Object) and returns unused. It converts F into a constructor. It performs the following steps when called:

  1. If F is an ECMAScript function object, then
    1. Assert: IsConstructor(F) is false.
    2. Assert: F is an extensible object that does not have a "prototype" own property.
    3. Set F.[[Construct]] to the definition specified in 10.2.2.
  2. Else,
    1. Set F.[[Construct]] to the definition specified in 10.3.2.
  3. Set F.[[ConstructorKind]] to base.
  4. If writablePrototype is not present, set writablePrototype to true.
  5. If prototype is not present, then
    1. Set prototype to OrdinaryObjectCreate(%Object.prototype%).
    2. Perform ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true }).
  6. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false }).
  7. Return unused.

10.2.6 MakeClassConstructor ( F )

The abstract operation MakeClassConstructor takes argument F (an ECMAScript function object) and returns unused. It performs the following steps when called:

  1. Assert: F.[[IsClassConstructor]] is false.
  2. Set F.[[IsClassConstructor]] to true.
  3. Return unused.

10.2.7 MakeMethod ( F, homeObject )

The abstract operation MakeMethod takes arguments F (an ECMAScript function object) and homeObject (an Object) and returns unused. It configures F as a method. It performs the following steps when called:

  1. Set F.[[HomeObject]] to homeObject.
  2. Return unused.

10.2.8 DefineMethodProperty ( homeObject, key, closure, enumerable )

The abstract operation DefineMethodProperty takes arguments homeObject (an Object), key (a property key or Private Name), closure (a function object), and enumerable (a Boolean) and returns a PrivateElement or unused. It performs the following steps when called:

  1. Assert: homeObject is an ordinary, extensible object with no non-configurable properties.
  2. If key is a Private Name, then
    1. Return PrivateElement { [[Key]]: key, [[Kind]]: method, [[Value]]: closure }.
  3. Else,
    1. Let desc be the PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }.
    2. Perform ! DefinePropertyOrThrow(homeObject, key, desc).
    3. Return unused.

10.2.9 SetFunctionName ( F, name [ , prefix ] )

The abstract operation SetFunctionName takes arguments F (a function object) and name (a property key or Private Name) and optional argument prefix (a String) and returns unused. It adds a "name" property to F. It performs the following steps when called:

  1. Assert: F is an extensible object that does not have a "name" own property.
  2. If name is a Symbol, then
    1. Let description be name's [[Description]] value.
    2. If description is undefined, set name to the empty String.
    3. Else, set name to the string-concatenation of "[", description, and "]".
  3. Else if name is a Private Name, then
    1. Set name to name.[[Description]].
  4. If F has an [[InitialName]] internal slot, then
    1. Set F.[[InitialName]] to name.
  5. If prefix is present, then
    1. Set name to the string-concatenation of prefix, the code unit 0x0020 (SPACE), and name.
    2. If F has an [[InitialName]] internal slot, then
      1. Optionally, set F.[[InitialName]] to name.
  6. Perform ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
  7. Return unused.

10.2.10 SetFunctionLength ( F, length )

The abstract operation SetFunctionLength takes arguments F (a function object) and length (a non-negative integer or +∞) and returns unused. It adds a "length" property to F. It performs the following steps when called:

  1. Assert: F is an extensible object that does not have a "length" own property.
  2. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
  3. Return unused.

10.2.11 FunctionDeclarationInstantiation ( func, argumentsList )

The abstract operation FunctionDeclarationInstantiation takes arguments func (an ECMAScript function object) and argumentsList (a List of ECMAScript language values) and returns either a normal completion containing unused or an abrupt completion. func is the function object for which the execution context is being established.

Note 1

When an execution context is established for evaluating an ECMAScript function a new Function Environment Record is created and bindings for each formal parameter are instantiated in that Environment Record. Each declaration in the function body is also instantiated. If the function's formal parameters do not include any default value initializers then the body declarations are instantiated in the same Environment Record as the parameters. If default value parameter initializers exist, a second Environment Record is created for the body declarations. Formal parameters and functions are initialized as part of FunctionDeclarationInstantiation. All other bindings are initialized during evaluation of the function body.

It performs the following steps when called:

  1. Let calleeContext be the running execution context.
  2. Let code be func.[[ECMAScriptCode]].
  3. Let strict be func.[[Strict]].
  4. Let formals be func.[[FormalParameters]].
  5. Let parameterNames be the BoundNames of formals.
  6. If parameterNames has any duplicate entries, let hasDuplicates be true. Otherwise, let hasDuplicates be false.
  7. Let simpleParameterList be IsSimpleParameterList of formals.
  8. Let hasParameterExpressions be ContainsExpression of formals.
  9. Let varNames be the VarDeclaredNames of code.
  10. Let varDeclarations be the VarScopedDeclarations of code.
  11. Let lexicalNames be the LexicallyDeclaredNames of code.
  12. Let functionNames be a new empty List.
  13. Let functionsToInitialize be a new empty List.
  14. For each element d of varDeclarations, in reverse List order, do
    1. If d is neither a VariableDeclaration nor a ForBinding nor a BindingIdentifier, then
      1. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration.
      2. Let fn be the sole element of the BoundNames of d.
      3. If functionNames does not contain fn, then
        1. Insert fn as the first element of functionNames.
        2. NOTE: If there are multiple function declarations for the same name, the last declaration is used.
        3. Insert d as the first element of functionsToInitialize.
  15. Let argumentsObjectNeeded be true.
  16. If func.[[ThisMode]] is lexical, then
    1. NOTE: Arrow functions never have an arguments object.
    2. Set argumentsObjectNeeded to false.
  17. Else if parameterNames contains "arguments", then
    1. Set argumentsObjectNeeded to false.
  18. Else if hasParameterExpressions is false, then
    1. If functionNames contains "arguments" or lexicalNames contains "arguments", then
      1. Set argumentsObjectNeeded to false.
  19. If strict is true or hasParameterExpressions is false, then
    1. NOTE: Only a single Environment Record is needed for the parameters, since calls to eval in strict mode code cannot create new bindings which are visible outside of the eval.
    2. Let env be the LexicalEnvironment of calleeContext.
  20. Else,
    1. NOTE: A separate Environment Record is needed to ensure that bindings created by direct eval calls in the formal parameter list are outside the environment where parameters are declared.
    2. Let calleeEnv be the LexicalEnvironment of calleeContext.
    3. Let env be NewDeclarativeEnvironment(calleeEnv).
    4. Assert: The VariableEnvironment of calleeContext is calleeEnv.
    5. Set the LexicalEnvironment of calleeContext to env.
  21. For each String paramName of parameterNames, do
    1. Let alreadyDeclared be ! env.HasBinding(paramName).
    2. NOTE: Early errors ensure that duplicate parameter names can only occur in non-strict functions that do not have parameter default values or rest parameters.
    3. If alreadyDeclared is false, then
      1. Perform ! env.CreateMutableBinding(paramName, false).
      2. If hasDuplicates is true, then
        1. Perform ! env.InitializeBinding(paramName, undefined).
  22. If argumentsObjectNeeded is true, then
    1. If strict is true or simpleParameterList is false, then
      1. Let ao be CreateUnmappedArgumentsObject(argumentsList).
    2. Else,
      1. NOTE: A mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters.
      2. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, env).
    3. If strict is true, then
      1. Perform ! env.CreateImmutableBinding("arguments", false).
      2. NOTE: In strict mode code early errors prevent attempting to assign to this binding, so its mutability is not observable.
    4. Else,
      1. Perform ! env.CreateMutableBinding("arguments", false).
    5. Perform ! env.InitializeBinding("arguments", ao).
    6. Let parameterBindings be the list-concatenation of parameterNames and « "arguments" ».
  23. Else,
    1. Let parameterBindings be parameterNames.
  24. Let iteratorRecord be CreateListIteratorRecord(argumentsList).
  25. If hasDuplicates is true, then
    1. Perform ? IteratorBindingInitialization of formals with arguments iteratorRecord and undefined.
  26. Else,
    1. Perform ? IteratorBindingInitialization of formals with arguments iteratorRecord and env.
  27. If hasParameterExpressions is false, then
    1. NOTE: Only a single Environment Record is needed for the parameters and top-level vars.
    2. Let instantiatedVarNames be a copy of the List parameterBindings.
    3. For each element n of varNames, do
      1. If instantiatedVarNames does not contain n, then
        1. Append n to instantiatedVarNames.
        2. Perform ! env.CreateMutableBinding(n, false).
        3. Perform ! env.InitializeBinding(n, undefined).
    4. Let varEnv be env.
  28. Else,
    1. NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.
    2. Let varEnv be NewDeclarativeEnvironment(env).
    3. Set the VariableEnvironment of calleeContext to varEnv.
    4. Let instantiatedVarNames be a new empty List.
    5. For each element n of varNames, do
      1. If instantiatedVarNames does not contain n, then
        1. Append n to instantiatedVarNames.
        2. Perform ! varEnv.CreateMutableBinding(n, false).
        3. If parameterBindings does not contain n, or if functionNames contains n, then
          1. Let initialValue be undefined.
        4. Else,
          1. Let initialValue be ! env.GetBindingValue(n, false).
        5. Perform ! varEnv.InitializeBinding(n, initialValue).
        6. NOTE: A var with the same name as a formal parameter initially has the same value as the corresponding initialized parameter.
  29. NOTE: Annex B.3.2.1 adds additional steps at this point.
  30. If strict is false, then
    1. Let lexEnv be NewDeclarativeEnvironment(varEnv).
    2. NOTE: Non-strict functions use a separate Environment Record for top-level lexical declarations so that a direct eval can determine whether any var scoped declarations introduced by the eval code conflict with pre-existing top-level lexically scoped declarations. This is not needed for strict functions because a strict direct eval always places all declarations into a new Environment Record.
  31. Else,
    1. Let lexEnv be varEnv.
  32. Set the LexicalEnvironment of calleeContext to lexEnv.
  33. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  34. For each element d of lexDeclarations, do
    1. NOTE: A lexically declared name cannot be the same as a function/generator declaration, formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! lexEnv.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! lexEnv.CreateMutableBinding(dn, false).
  35. Let privateEnv be the PrivateEnvironment of calleeContext.
  36. For each Parse Node f of functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
    3. Perform ! varEnv.SetMutableBinding(fn, fo, false).
  37. Return unused.
Note 2

B.3.2 provides an extension to the above algorithm that is necessary for backwards compatibility with web browser implementations of ECMAScript that predate ECMAScript 2015.