每個(gè)執(zhí)行環(huán)境都有一個(gè)關(guān)聯(lián)的變量環(huán)境。當(dāng)在一個(gè)執(zhí)行環(huán)境下評(píng)估一段 ECMA 腳本時(shí),變量和函數(shù)定義會(huì)以綁定的形式添加到這個(gè)變量環(huán)境的 環(huán)境記錄 中。對(duì)于函數(shù) 函數(shù)代碼,參數(shù)也同樣會(huì)以綁定的形式添加到這個(gè)變量環(huán)境的 環(huán)境記錄 中。
選擇使用哪一個(gè)、哪一類型的 環(huán)境記錄 來綁定定義,是由執(zhí)行環(huán)境下執(zhí)行的 ECMA 腳本的類型決定的,而其它部分的邏輯是相同的。當(dāng)進(jìn)入一個(gè)執(zhí)行環(huán)境時(shí),會(huì)按以下步驟在變量環(huán)境上創(chuàng)建綁定,其中使用到調(diào)用者提供的代碼設(shè)為 code,如果執(zhí)行的是 函數(shù)代碼 ,則設(shè) 參數(shù)列表 為 args:
- 令 env 為當(dāng)前運(yùn)行的執(zhí)行環(huán)境的環(huán)境變量的 環(huán)境記錄 。
- 如果 code 是 eval 代碼 ,則令 configurableBindings 為 true,否則令 configurableBindings 為 false。
- 如果代碼是 嚴(yán)格模式下的代碼 ,則令 strict 為 true,否則令 strict 為 false。
- 如果代碼為 函數(shù)代碼 ,則:令 func 為通過 [[Call]] 內(nèi)部屬性初始化 code 的執(zhí)行的函數(shù)對(duì)象。令 names 為 func 的 [[FormalParameters]] 內(nèi)部屬性。令 argCount 為 args 中元素的數(shù)量。令 n 為數(shù)字類型,其值為 0。按列表順序遍歷 names,對(duì)于每一個(gè)字符串 argName:令 n 的值為 n 當(dāng)前值加 1。如果 n 大于 argCount,則令 v 為 undefined,否則令 v 為 args 中的第 n 個(gè)元素。以 argName 為參數(shù),調(diào)用 env 的 HasBinding 具體方法,并令 argAlreadyDeclared 為調(diào)用的結(jié)果。如果 argAlreadyDeclared 的值為 false,以 argName 為參數(shù)調(diào)用 env 的 CreateMutableBinding 具體方法。以 argName、v 和 strict 為參數(shù),調(diào)用 env 的 SetMutableBinding 具體方法。
- 按源碼順序遍歷 code,對(duì)于每一個(gè) FunctionDeclaration 表達(dá)式 f:令 fn 為 FunctionDeclaration 表達(dá)式 f 中的 標(biāo)識(shí)符 。按 第 13 章 中所述的步驟初始化 FunctionDeclaration 表達(dá)式 ,并令 fo 為初始化的結(jié)果。以 fn 為參數(shù),調(diào)用 env 的 HasBinding 具體方法,并令 argAlreadyDeclared 為調(diào)用的結(jié)果。如果 argAlreadyDeclared 的值為 false,以 fn 和 configurableBindings 為參數(shù)調(diào)用 env 的 CreateMutableBinding 具體方法。否則如果 env 是全局環(huán)境的 環(huán)境記錄 對(duì)象,則:令 go 為全局對(duì)象。以 fn 為參數(shù),調(diào)用 go 和 [[GetProperty]] 內(nèi)部方法,并令 existingProp 為調(diào)用的結(jié)果。如果 existingProp.[[Configurable]] 的值為 true,則:以 fn、由 {[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: configurableBindings } 組成的 屬性描述符 和 true 為參數(shù),調(diào)用go 的 [[DefineOwnProperty]] 內(nèi)部方法。否則如果 IsAccessorDescrptor(existingProp) 的結(jié)果為真,或 existingProp 的特性中沒有 {[[Writable]]: true, [[Enumerable]]: true},則:拋出一個(gè) TypeError 異常。以 fn、fo 和 strict 為參數(shù),調(diào)用 env 的 SetMutableBinding 具體方法。
- 以 arguments 為參數(shù),調(diào)用 env 的 HasBinding 具體方法,并令 argumentsAlreadyDeclared 為調(diào)用的結(jié)果。
- 如果 code 是 函數(shù)代碼 ,并且 argumentsAlreadyDeclared 為 false,則:以 fn、names、args、env 和 strict 為參數(shù),調(diào)用 CreateArgumentsObject 抽象運(yùn)算函數(shù),并令 argsObj 為調(diào)用的結(jié)果。如果 strict 為 true,則:以字符串 "arguments" 為參數(shù),調(diào)用 env 的 CreateImmutableBinding 具體方法。以字符串 "arguments" 和 argsObj 為參數(shù),調(diào)用 env 的 InitializeImmutableBinding 具體函數(shù)。否則:以字符串 "arguments" 為參數(shù),調(diào)用 env 的 CreateMutableBinding 具體方法。以字符串 "arguments"、argsObj 和 false 為參數(shù),調(diào)用 env 的 SetMutableBinding 具體函數(shù)。
- 按源碼順序遍歷 code,對(duì)于每一個(gè) VariableDeclaration 和 VariableDeclarationNoIn 表達(dá)式:令 dn 為 d 中的標(biāo)識(shí)符。以 dn 為參數(shù),調(diào)用 env 的 HasBinding 具體方法,并令 varAlreadyDeclared 為調(diào)用的結(jié)果。如果 varAlreadyDeclared 為 false,則:以 dn 和 configurableBindings 為參數(shù),調(diào)用 env 的 CreateMutableBinding 具體方法。以 dn、undefined 和 strict 為參數(shù),調(diào)用 env 的 SetMutableBinding 具體方法。
更多建議: