为什么没有var语句声明的变量是全局的

时间:2014-03-04 03:57:08

标签: javascript variables global

请考虑以下代码:

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

我想了解为什么newvar-->"SomeStr"绑定包含在全局命名空间中?根据规范,§11.13.1“简单分配(=)”:

  

生产 AssignmentExpression LeftHandSideExpression = AssignmentExpression 评估如下:

     
      
  1. lref 成为评估 LeftHandSideExpression 的结果。
  2.   
  3. rref 成为评估 AssignmentExpression 的结果。
  4.   
  5. rval 为GetValue( rref )。
  6.   
  7. 如果满足以下条件,则抛出 SyntaxError 异常:   
        
    • 类型( lref )是参考 true
    •   
    • IsStrictReference( lref true
    •   
    • 类型(GetBase( lref ))是环境记录
    •   
    • GetReferencedName( lref )是"eval""arguments"
    •   
  8.   
  9. 调用PutValue( lref rval )。
  10.   
  11. 返回 rval
  12.   

newvar是一个标识符。从§10.3.1“标识符解析”:

  

在执行ECMAScript代码期间,使用以下算法评估语法生成 PrimaryExpression Identifier

     
      
  1. env 成为正在运行的执行上下文的LexicalEnvironment。
  2.   
  3. 如果正在评估的语法制作包含在严格模式代码中,那么让严格 为真,否则让严格为的即可。
  4.   
  5. 返回调用GetIdentifierReference函数的结果,将 env Identifier strict 作为参数传递。
  6.   

GetIdentifierReference( lex name strict )在其自己的第10.2.2.1节中定义,其中说:

  

[...]调用时,执行以下步骤:

     
      
  1. 如果 lex 的值是 null ,那么   
        
    1. [ a ]返回类型为Reference的值,其基值为未定义,其引用名称为 name ,其严格模式标志严格
    2.   
  2.   
  3. envRec 成为 lex 的环境记录。
  4.   
  5. 存在是调用 envRec 传递 name 的HasBinding( N )具体方法的结果参数 N
  6.   
  7. 如果存在true,那么   
        
    1. [ a ]返回类型为Reference的值,其基值为 envRec ,其引用名称为 name ,其严格模式标志严格
    2.   
  8.   
  9. 否则   
        
    1. [ a ]让外部 lex 的外部环境参考值。
    2.   
    3. [ b ]返回调用GetIdentifierReference的结果,将外部名称 strict 作为参数传递。
    4.   
  10.   

因此,我们在评估newvar标识符后,将返回名称为newvar且基值为undefined的引用。但是,当我们在评估PutValue(lref,rval)期间尝试调用AssignmentExpression

  
      
  1. 如果Type(V)不是Reference,则抛出ReferenceError异常。
  2.   
  3. 让base成为调用GetBase(V)的结果。
  4.   
  5. 如果IsUnresolvableReference(V),那么

         

    一个。如果IsStrictReference(V)为真,那么

     i. Throw ReferenceError exception.
    
         

    湾调用全局对象的[[Put]]内部方法,为属性名称传递GetReferencedName(V),为值传递W,为投掷标志传递false。

  6.   
  7. 如果是IsPropertyReference(V),那么

         

    一个。如果HasPrimitiveBase(V)为false,则将put作为base的[[Put]]内部方法,否则让put为下面定义的特殊[[Put]]内部方法。

         

    湾使用base作为此值调用put internal方法,并为属性名称传递GetReferencedName(V),为值传递W,为Throw标志传递IsStrictReference(V)。

  8.   
  9. 其他基数必须是基数为环境记录的引用。所以,     一个。调用Set的基于SetMutableBinding(10.2.1)的具体方法,将GetReferencedName(V),W和IsStrictReference(V)作为参数传递。

  10.   
  11. 返回。
  12.   

因此SetMutableBinding会打电话。但是base是undefined并且必须引发TypeError。而是将newvar--->"SomeStr"绑定添加到全局命名空间。请解释一下为什么?

0 个答案:

没有答案