12.2 Variable statement

2010-05-23

VariableStatement :
var VariableDeclaration ;

VariableDeclarationList :
VariableDeclaration
VariableDeclarationList , VariableDeclaration

Missing NoIn statement?

VariableDeclarationListNoIn :
VariableDeclarationNoIn
VariableDeclarationListNoIn , VariableDeclarationNoIn

VariableDeclaration :
Identifier Initialiser(opt)

VariableDeclarationNoIn :
Identifier InitialiserNoIn(opt)

Initialiser :
= AssignmentExpression

InitialiserNoIn :
= AssignmentExpressionNoIn

The var statement declares variables as defined in 10.5 and initialises them to undefined when created. The initialiser is assigned at the time of execution of the statement, not when the variable is declared. So when a var statement is executed only initialisers actually do something, since all the variables will have been created at that point.

Code: (Meta Ecma)
function evaluate(var VariableDeclarationList ;) {
evaluate(VariableDeclarationList);
return Completion('normal', undefined, undefined);
}


Code: (Meta Ecma)
function evaluate(VariableDeclaration) {
return evaluate(VariableDeclaration);
}


Code: (Meta Ecma)
function evaluate(VariableDeclarationList , VariableDeclaration) {
evaluate(VariableDeclarationList);
evaluate(VariableDeclaration);
// No return here??
}

This case proves why evaluate must have a Production and Matches parameter... This definition would clash with 11.1.2.

Code: (Meta Ecma)
function evaluate(Identifier) {
// "return a String value containing the same sequence of characters as in the Identifier"
return Identifier; // todo: create interface for that :)
// return value is used in 12.6.4, for .. in
}


Code: (Meta Ecma)
function evaluate(Identifier) {
var lhs = evaluate(Identifier); // 11.1.2, returns Reference of bound Identifier
var rhs = evaluate(Initialiser);
var value = GetValue(rhs);
PutValue(lhs, value);
// "return a String value containing the same sequence of characters as in the Identifier"
return Identifier; // todo: create interface for that :)
// return value is used in 12.6.4, for .. in
}

The specification notes that if a VariableDeclaration is nested within a WithStatement and the Identifier in the VariableDeclaration is the same as a prototype name of the binding object of the WithStatement's object environment record, then step 4 (call to PutValue) will assign value to the property instead of to the VariableEnvironment binding of the Identifier.

In other words, if
- you declare a variable, and
- use an initialiser, and
- are in a with block, and
- the variable name also exists as a property of the prototype of the with's object, then
the property of the prototype is set to the initialiser instead. (Why? Due to 11.1.2? Due to GetValue? Due to PutValue? Special condition? Need to find out. And is the property of the prototype changed? Or is the property of the object set to the initialiser?)

Code: (Meta Ecma)
function evaluate(AssignmentExpression) {
return evaluate(AssignmentExpression);
}


The NoIn versions behave exactly the same.