14.3 Declarations and the Variable Statement

14.3.1 Let and Const Declarations

Note

let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer's AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

Syntax

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.1.1 Static Semantics: Early Errors

LexicalDeclaration : LetOrConst BindingList ; LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 Runtime Semantics: Evaluation

LexicalDeclaration : LetOrConst BindingList ;
  1. Let next be the result of evaluating BindingList.
  2. ReturnIfAbrupt(next).
  3. Return NormalCompletion(empty).
BindingList : BindingList , LexicalBinding
  1. Let next be the result of evaluating BindingList.
  2. ReturnIfAbrupt(next).
  3. Return the result of evaluating LexicalBinding.
LexicalBinding : BindingIdentifier
  1. Let lhs be ResolveBinding(StringValue of BindingIdentifier).
  2. Return InitializeReferencedBinding(lhs, undefined).
Note

A static semantics rule ensures that this form of LexicalBinding never occurs in a const declaration.

LexicalBinding : BindingIdentifier Initializer
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ResolveBinding(bindingId).
  3. If IsAnonymousFunctionDefinition(Initializer) is true, then
    1. Let value be NamedEvaluation of Initializer with argument bindingId.
  4. Else,
    1. Let rhs be the result of evaluating Initializer.
    2. Let value be ? GetValue(rhs).
  5. Return InitializeReferencedBinding(lhs, value).
LexicalBinding : BindingPattern Initializer
  1. Let rhs be the result of evaluating Initializer.
  2. Let value be ? GetValue(rhs).
  3. Let env be the running execution context's LexicalEnvironment.
  4. Return the result of performing BindingInitialization for BindingPattern using value and env as the arguments.

14.3.2 Variable Statement

Note

A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Environment Record is instantiated and are initialized to undefined when created. Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collectively define only one variable. A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer's AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.

Syntax

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 Runtime Semantics: Evaluation

VariableStatement : var VariableDeclarationList ;
  1. Let next be the result of evaluating VariableDeclarationList.
  2. ReturnIfAbrupt(next).
  3. Return NormalCompletion(empty).
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. Let next be the result of evaluating VariableDeclarationList.
  2. ReturnIfAbrupt(next).
  3. Return the result of evaluating VariableDeclaration.
VariableDeclaration : BindingIdentifier
  1. Return NormalCompletion(empty).
VariableDeclaration : BindingIdentifier Initializer
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId).
  3. If IsAnonymousFunctionDefinition(Initializer) is true, then
    1. Let value be NamedEvaluation of Initializer with argument bindingId.
  4. Else,
    1. Let rhs be the result of evaluating Initializer.
    2. Let value be ? GetValue(rhs).
  5. Return ? PutValue(lhs, value).
Note

If a VariableDeclaration is nested within a with statement and the BindingIdentifier in the VariableDeclaration is the same as a property name of the binding object of the with statement's object Environment Record, then step 5 will assign value to the property instead of assigning to the VariableEnvironment binding of the Identifier.

VariableDeclaration : BindingPattern Initializer
  1. Let rhs be the result of evaluating Initializer.
  2. Let rval be ? GetValue(rhs).
  3. Return the result of performing BindingInitialization for BindingPattern passing rval and undefined as arguments.

14.3.3 Destructuring Binding Patterns

Syntax

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 Runtime Semantics: PropertyBindingInitialization

With parameters value and environment.

Note
These collect a list of all bound property names rather than just empty completion.
BindingPropertyList : BindingPropertyList , BindingProperty
  1. Let boundNames be ? PropertyBindingInitialization of BindingPropertyList with arguments value and environment.
  2. Let nextNames be ? PropertyBindingInitialization of BindingProperty with arguments value and environment.
  3. Append each item in nextNames to the end of boundNames.
  4. Return boundNames.
BindingProperty : SingleNameBinding
  1. Let name be the string that is the only element of BoundNames of SingleNameBinding.
  2. Perform ? KeyedBindingInitialization for SingleNameBinding using value, environment, and name as the arguments.
  3. Return a List whose sole element is name.
BindingProperty : PropertyName : BindingElement
  1. Let P be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(P).
  3. Perform ? KeyedBindingInitialization of BindingElement with value, environment, and P as the arguments.
  4. Return a List whose sole element is P.

14.3.3.2 Runtime Semantics: RestBindingInitialization

With parameters value, environment, and excludedNames.

BindingRestProperty : ... BindingIdentifier
  1. Let lhs be ? ResolveBinding(StringValue of BindingIdentifier, environment).
  2. Let restObj be ! OrdinaryObjectCreate(%Object.prototype%).
  3. Perform ? CopyDataProperties(restObj, value, excludedNames).
  4. If environment is undefined, return PutValue(lhs, restObj).
  5. Return InitializeReferencedBinding(lhs, restObj).

14.3.3.3 Runtime Semantics: KeyedBindingInitialization

With parameters value, environment, and propertyName.

Note

When undefined is passed for environment it indicates that a PutValue operation should be used to assign the initialization value. This is the case for formal parameter lists of non-strict functions. In that case the formal parameter bindings are preinitialized in order to deal with the possibility of multiple parameters with the same name.

BindingElement : BindingPattern Initializeropt
  1. Let v be ? GetV(value, propertyName).
  2. If Initializer is present and v is undefined, then
    1. Let defaultValue be the result of evaluating Initializer.
    2. Set v to ? GetValue(defaultValue).
  3. Return the result of performing BindingInitialization for BindingPattern passing v and environment as arguments.
SingleNameBinding : BindingIdentifier Initializeropt
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId, environment).
  3. Let v be ? GetV(value, propertyName).
  4. If Initializer is present and v is undefined, then
    1. If IsAnonymousFunctionDefinition(Initializer) is true, then
      1. Set v to the result of performing NamedEvaluation for Initializer with argument bindingId.
    2. Else,
      1. Let defaultValue be the result of evaluating Initializer.
      2. Set v to ? GetValue(defaultValue).
  5. If environment is undefined, return ? PutValue(lhs, v).
  6. Return InitializeReferencedBinding(lhs, v).