1

Consider the following code:

var somevar;
function(){
    newvar="SomeStr";
}();

I want to understand why does newvar-->"SomeStr" binding contained into a global namespace? From the spec, §11.13.1 "Simple Assignment (=)":

The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let rref be the result of evaluating AssignmentExpression.
  3. Let rval be GetValue(rref).
  4. Throw a SyntaxError exception if the following conditions are all true:
    • Type(lref) is Reference is true
    • IsStrictReference(lref) is true
    • Type(GetBase(lref)) is Environment Record
    • GetReferencedName(lref) is either "eval" or "arguments"
  5. Call PutValue(lref, rval).
  6. Return rval.

newvar is an identifier. From §10.3.1 "Identifier Resolution":

During execution of ECMAScript code, the syntactic production PrimaryExpression : Identifier is evaluated using the following algorithm:

  1. Let env be the running execution context’s LexicalEnvironment.
  2. If the syntactic production that is being evaluated is contained in a strict mode code, then let strict be true, else let strict be false.
  3. Return the result of calling GetIdentifierReference function passing env, Identifier, and strict as arguments.

GetIdentifierReference (lex, name, strict) is defined in its own section §10.2.2.1, which says:

[…] When called, the following steps are performed:

  1. If lex is the value null, then
    1. [a] Return a value of type Reference whose base value is undefined, whose referenced name is name, and whose strict mode flag is strict.
  2. Let envRec be lex’s environment record.
  3. Let exists be the result of calling the HasBinding(N) concrete method of envRec passing name as the argument N.
  4. If exists is true, then
    1. [a] Return a value of type Reference whose base value is envRec, whose referenced name is name, and whose strict mode flag is strict.
  5. Else
    1. [a] Let outer be the value of lex’s outer environment reference.
    2. [b] Return the result of calling GetIdentifierReference passing outer, name, and strict as arguments.

Thus we have that after evaluating newvar identifier, reference with the name newvar and base value undefined will be returned. But when we've tried to invoke PutValue(lref,rval) during the evaluating of AssignmentExpression we have

  1. If Type(V) is not Reference, throw a ReferenceError exception.
  2. Let base be the result of calling GetBase(V).
  3. If IsUnresolvableReference(V), then

    a. If IsStrictReference(V) is true, then

     i. Throw ReferenceError exception.
    

    b. Call the [[Put]] internal method of the global object, passing GetReferencedName(V) for the property name, W for the value, and false for the Throw flag.

  4. Else if IsPropertyReference(V), then

    a. If HasPrimitiveBase(V) is false, then let put be the [[Put]] internal method of base, otherwise let put be the special [[Put]] internal method defined below.

    b. Call the put internal method using base as its this value, and passing GetReferencedName(V) for the property name, W for the value, and IsStrictReference(V) for the Throw flag.

  5. Else base must be a reference whose base is an environment record. So, a. Call the SetMutableBinding (10.2.1) concrete method of base, passing GetReferencedName(V), W, and IsStrictReference(V) as arguments.

  6. Return.

Thus SetMutableBinding will call. But base is undefined and TypeError must be raised. Instead the newvar--->"SomeStr" binding will be added to a global namespace. Please explain me why?

ruakh
  • 175,680
  • 26
  • 273
  • 307
St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 4
    Complete ans to your question [What is the function of the var keyword in ECMAScript 262 3rd Edition/Javascript 1.5](http://stackoverflow.com/questions/1470488/what-is-the-function-of-the-var-keyword-in-ecmascript-262-3rd-edition-javascript#answer-1471738) – Deepak Ingole Mar 04 '14 at 04:09
  • @Pilot So why in the spec said that If lex is the value null, then a. Return a value of type Reference whose base value is **undefined**, whose referenced name is name, and whose strict mode flag is strict. Why the base value is not a global object environment? – St.Antario Mar 04 '14 at 05:19
  • I don't understand why you think a TypeError would be raised. You don't quote any part of the spec that throws any TypeError for any reason (relevant or otherwise). – ruakh Mar 07 '14 at 16:47

0 Answers0