1. Lexical Environment与Environment Record
从ECMAScript规范 Executable Code and Execution Contexts这一章,我们知道,
一个Lexical Environment是一个规范内置的类型(specification type),
它包括两个字段,Environment Record,还有一个指向外层Lexical Environment的可空引用。
Lexical Environment一般分为global environment,module environment,以及function environment。
Environment Record可以用一个抽象类来实现,
它包括3个子类:declarative Environment Record,object Environment Record,global Environment Record。
declarative Environment Record又有两个子类:
function Environment Records和module Environment Records
其中,declarative Environment Record用来解决,函数声明,变量声明,catch语句中的标识符解析问题。object Environment Record用来解决,with语句中的标识符解析问题。
function Environment Records是declarative Environment Record的一种,
在函数体被执行之前会初始化一个新的function Environment Record,
function Environment Records或者会或者不会建立一个新的this绑定,
如果是arrow function,就不建立新的this绑定,
如果是function,就建立新的this绑定。
注:
如果是arrow function,就不建立新的this绑定,而是使用外层的this绑定。
这一点没有显式说明,只是看到HasThisBinding会返回false,
GetThisBinding也只会处理不是arrow function的情况。
关于arrow function处理this的方式,在这里被不明显的提到,
14.2.16Runtime Semantics: Evaluation
因此,要判断arrow function中this的指向,要看外层Lexical Environment中this是什么。
2. BlockStatement
我们考虑BlockStatement,看看语句块是怎样建立declarative Environment Record的,
以及里面的this如何解析。
于是,我们应该看这里,
13.2.13Runtime Semantics: Evaluation
其中调用了,NewDeclarativeEnvironment
创建了一个新的Lexical Environment,并初始化它的两个字段,EnvironmentRecord以及指向外层Lexical Environment的引用。
注意,这里创建的是declarative Environment Record,它是function Environment Records的父类,并不会建立this绑定。
因此,BlockStatement中的this,应该与外层Lexical Environment中的this一致。
function f() {
{
return this;
}
}
a = {};
alert(f.call(a) === a); // true