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