请考虑以下代码:
var somevar;
function(){
newvar="SomeStr";
}();
我想了解为什么newvar-->"SomeStr"
绑定包含在全局命名空间中?根据规范,§11.13.1“简单分配(=
)”:
生产 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 评估如下:
- 让 lref 成为评估 LeftHandSideExpression 的结果。
- 让 rref 成为评估 AssignmentExpression 的结果。
- 让 rval 为GetValue( rref )。
- 如果满足以下条件,则抛出 SyntaxError 异常:
- 类型( lref )是参考 true
- IsStrictReference( lref ) true
- 类型(GetBase( lref ))是环境记录
- GetReferencedName( lref )是
"eval"
或"arguments"
- 调用PutValue( lref , rval )。
- 返回 rval 。
醇>
newvar
是一个标识符。从§10.3.1“标识符解析”:
在执行ECMAScript代码期间,使用以下算法评估语法生成 PrimaryExpression : Identifier :
- 让 env 成为正在运行的执行上下文的LexicalEnvironment。
- 如果正在评估的语法制作包含在严格模式代码中,那么让严格 为真,否则让严格为的假即可。
- 返回调用GetIdentifierReference函数的结果,将 env , Identifier 和 strict 作为参数传递。
醇>
GetIdentifierReference( lex , name , strict )在其自己的第10.2.2.1节中定义,其中说:
[...]调用时,执行以下步骤:
- 如果 lex 的值是 null ,那么
- [ a ]返回类型为Reference的值,其基值为未定义,其引用名称为 name ,其严格模式标志严格。
- 让 envRec 成为 lex 的环境记录。
- 让存在是调用 envRec 传递 name 的HasBinding( N )具体方法的结果参数 N 。
- 如果存在是
true
,那么
- [ a ]返回类型为Reference的值,其基值为 envRec ,其引用名称为 name ,其严格模式标志严格。
- 否则
醇>
- [ a ]让外部为 lex 的外部环境参考值。
- [ b ]返回调用GetIdentifierReference的结果,将外部,名称和 strict 作为参数传递。
因此,我们在评估newvar
标识符后,将返回名称为newvar
且基值为undefined
的引用。但是,当我们在评估PutValue(lref,rval)
期间尝试调用AssignmentExpression
- 如果Type(V)不是Reference,则抛出ReferenceError异常。
- 让base成为调用GetBase(V)的结果。
如果IsUnresolvableReference(V),那么
一个。如果IsStrictReference(V)为真,那么
i. Throw ReferenceError exception.
湾调用全局对象的[[Put]]内部方法,为属性名称传递GetReferencedName(V),为值传递W,为投掷标志传递false。
如果是IsPropertyReference(V),那么
一个。如果HasPrimitiveBase(V)为false,则将put作为base的[[Put]]内部方法,否则让put为下面定义的特殊[[Put]]内部方法。
湾使用base作为此值调用put internal方法,并为属性名称传递GetReferencedName(V),为值传递W,为Throw标志传递IsStrictReference(V)。
其他基数必须是基数为环境记录的引用。所以, 一个。调用Set的基于SetMutableBinding(10.2.1)的具体方法,将GetReferencedName(V),W和IsStrictReference(V)作为参数传递。
- 返回。
醇>
因此SetMutableBinding
会打电话。但是base是undefined
并且必须引发TypeError。而是将newvar--->"SomeStr"
绑定添加到全局命名空间。请解释一下为什么?