html代码在线运行环境,ES5/可执行代码与执行环境
可執(zhí)行代碼類型
一共有三種 ECMA 腳本可執(zhí)行代碼:
全局代碼是指被作為 ECMAScript
Eval 代碼是指提供給 eval 內(nèi)置函數(shù)的源代碼文本。更精確地說,如果傳遞給 eval 內(nèi)置函數(shù)的參數(shù)為一個(gè)字符串,該字符串將被作為 ECMA 腳本 eval 的調(diào)用過程中,eval 代碼作為該 全局代碼部分。
函數(shù)代碼是指作為 函數(shù)代碼不包括作為其嵌套函數(shù)的 函數(shù)代碼同時(shí)還特指以構(gòu)造器方式調(diào)用 Function 內(nèi)置對(duì)象時(shí)所提供的源代碼文本。更精確地說,調(diào)用 Function 構(gòu)造器時(shí)傳遞的最后一個(gè)參數(shù)將被轉(zhuǎn)換為字符串并作為 Function 構(gòu)造器時(shí),傳遞了一個(gè)以上的參數(shù),除最后一個(gè)參數(shù)以外的其他參數(shù)都將轉(zhuǎn)換為字符串,并以逗號(hào)作為分隔符連接在一起成為一個(gè)字符串,該字符串被解析為 Function 對(duì)象時(shí)所提供的函數(shù)代碼,并不包括作為其嵌套函數(shù)的
嚴(yán)格模式下的代碼
一個(gè) ECMA 腳本程序的語法單元可以使用非嚴(yán)格或嚴(yán)格模式下的語法及語義進(jìn)行處理。當(dāng)使用嚴(yán)格模式進(jìn)行處理時(shí),以上三種代碼將被稱為嚴(yán)格全局代碼、嚴(yán)格 eval 代碼和嚴(yán)格函數(shù)代碼。當(dāng)符合以下條件時(shí),代碼將被解析為嚴(yán)格模式下的代碼:
詞法環(huán)境
詞法環(huán)境是一個(gè)用于定義特定變量和函數(shù)標(biāo)識(shí)符在 ECMAScript 代碼的詞法嵌套結(jié)構(gòu)上關(guān)聯(lián)關(guān)系的規(guī)范類型。一個(gè)詞法環(huán)境由一個(gè)環(huán)境記錄項(xiàng)和可能為空的外部詞法環(huán)境引用構(gòu)成。通常詞法環(huán)境會(huì)與 ECMAScript 代碼諸如 詞法環(huán)境被創(chuàng)建出來。
環(huán)境記錄項(xiàng)記錄了在其關(guān)聯(lián)的詞法環(huán)境范圍中創(chuàng)建的標(biāo)識(shí)符綁定。
外部詞法環(huán)境引用用于表示詞法環(huán)境的邏輯嵌套關(guān)系模型。(內(nèi)部)詞法環(huán)境的外部引用是邏輯上包含內(nèi)部詞法環(huán)境的詞法環(huán)境。外部詞法環(huán)境自然也可能有多個(gè)內(nèi)部詞法環(huán)境。例如,如果一個(gè)
--Undefined (talk) 04:46, 28 January 2014 (UTC)詞法環(huán)境和環(huán)境記錄項(xiàng)是純粹的規(guī)范機(jī)制,而不需要 ECMAScript 的實(shí)現(xiàn)保持一致。ECMAScript 程序不可能直接訪問或者更改這些值。
環(huán)境記錄項(xiàng)
出于標(biāo)準(zhǔn)規(guī)范的目的,可以將環(huán)境記錄項(xiàng)理解為面向?qū)ο笾械囊粋€(gè)簡單繼承結(jié)構(gòu),其中環(huán)境記錄項(xiàng)是一個(gè)抽象類,有兩個(gè)具體實(shí)現(xiàn)類,分別為聲明式環(huán)境記錄項(xiàng)和對(duì)象式環(huán)境記錄項(xiàng)。抽象類包含了 表17 所描述的抽象方法定義,針對(duì)每一個(gè)具體實(shí)現(xiàn)類,每個(gè)抽象方法都有不同的具體算法。
表17 - 環(huán)境記錄項(xiàng)的抽象方法
方法
作用
HasBinding(N)
判斷環(huán)境記錄項(xiàng)是否包含對(duì)某個(gè)標(biāo)識(shí)符的綁定。如果包含該綁定則返回 true,反之返回 false。其中字符串 N 是標(biāo)識(shí)符文本。
CreateMutableBinding(N, D)
在環(huán)境記錄項(xiàng)中創(chuàng)建一個(gè)新的可變綁定。其中字符串 N 指定綁定名稱。如果可選參數(shù) D 的值為 true,則該綁定在后續(xù)操作中可以被刪除。
SetMutableBinding(N, V, S)
在環(huán)境記錄項(xiàng)中設(shè)置一個(gè)已經(jīng)存在的綁定的值。其中字符串 N 指定綁定名稱。V 用于指定綁定的值,可以是任何 ECMA 腳本語言的類型。S 是一個(gè)布爾類型的標(biāo)記,當(dāng) S 為 true 并且該綁定不允許賦值時(shí),則拋出一個(gè) TypeError 異常。S 用于指定是否為嚴(yán)格模式。
GetBindingValue(N, S)
返回環(huán)境記錄項(xiàng)中一個(gè)已經(jīng)存在的綁定的值。其中字符串 N 指定綁定的名稱。S 用于指定是否為嚴(yán)格模式。如果 S 的值為 true 并且該綁定不存在或未初始化,則拋出一個(gè) ReferenceError 異常。
DeleteBinding(N)
從環(huán)境記錄項(xiàng)中刪除一個(gè)綁定。其中字符串 N 指定綁定的名稱。如果 N 指定的綁定存在,將其刪除并返回 true。如果綁定存在但無法刪除則返回 false。如果綁定不存在則返回 true。
ImplicitThisValue()
當(dāng)從該環(huán)境記錄項(xiàng)的綁定中獲取一個(gè)函數(shù)對(duì)象并且調(diào)用時(shí),該方法返回該函數(shù)對(duì)象使用的 this 對(duì)象的值。
聲明式環(huán)境記錄項(xiàng)
每個(gè)聲明式環(huán)境記錄項(xiàng)都與一個(gè)包含變量和(或)函數(shù)聲明的 ECMA 腳本的程序作用域相關(guān)聯(lián)。聲明式環(huán)境記錄項(xiàng)用于綁定作用域內(nèi)定義的一系列標(biāo)識(shí)符。
除了所有環(huán)境記錄項(xiàng)都支持的可變綁定外,聲明式環(huán)境記錄項(xiàng)還提供不可變綁定。
在不可變綁定中,一個(gè)標(biāo)識(shí)符與它的值之間的關(guān)聯(lián)關(guān)系建立之后,就無法改變。創(chuàng)建和初始化不可變綁定是兩個(gè)獨(dú)立的過程,因此類似的綁定可以處在已初始化階段或者未初始化階段。除了環(huán)境記錄項(xiàng)定義的抽象方法外,聲明式環(huán)境記錄項(xiàng)還支持 表18 中列出的方法:
表18 - 聲明式環(huán)境記錄項(xiàng)的額外方法
方法
作用
在環(huán)境記錄項(xiàng)中創(chuàng)建一個(gè)未初始化的不可變綁定。其中字符串 N 指定綁定名稱。
在環(huán)境記錄項(xiàng)中設(shè)置一個(gè)已經(jīng)創(chuàng)建但未初始化的不可變綁定的值。其中字符串 N 指定綁定名稱。V 用于指定綁定的值,可以是任何 ECMA 腳本語言的類型。
環(huán)境記錄項(xiàng)定義的方法的具體行為將由以下算法給予描述。
HasBinding(N)
聲明式環(huán)境記錄項(xiàng)的 HasBinding 具體方法用于簡單地判斷作為參數(shù)的標(biāo)識(shí)符是否是當(dāng)前對(duì)象綁定的標(biāo)識(shí)符之一:
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
如果 envRec 有一個(gè)名稱為 N 的綁定,返回 true。
如果沒有該綁定,返回 false。
CreateMutableBinding(N, D)
聲明式環(huán)境記錄項(xiàng)的 CreateMutableBinding 具體方法會(huì)創(chuàng)建一個(gè)名稱為 N 的綁定,并初始化其值為 undefined。方法調(diào)用時(shí),當(dāng)前環(huán)境記錄項(xiàng)中不能存在 N 的綁定。如果調(diào)用時(shí)提供了布爾類型的參數(shù) D 且其值為 true,則新建的綁定被標(biāo)記為可刪除。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
執(zhí)行斷言:envRec 沒有 N 的綁定。
在 envRec 中為 N 創(chuàng)建一個(gè)可變綁定,并將綁定的值設(shè)置為 undefined。如果 D 為 true 則新創(chuàng)建的綁定可在后續(xù)操作中通過調(diào)用 DeleteBinding 刪除。
SetMutableBinding(N, V, S)
聲明式環(huán)境記錄項(xiàng)的 SetMutableBinding 具體方法嘗試將當(dāng)前名稱為參數(shù) N 的綁定的值修改為參數(shù) V 指定的值。方法調(diào)用時(shí),必須存在 N 的綁定。如果該綁定為不可變綁定,并且 S 的值為 true,則拋出一個(gè) TypeError 異常。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
執(zhí)行斷言:envRec 必須有 N 的綁定。
如果 envRec 中 N 的綁定為可變綁定,則將其值修改為 V。
否則該操作會(huì)嘗試修改一個(gè)不可變綁定的值,因此如果 S 的值為 true,則拋出一個(gè) TypeError 異常。
GetBindingValue(N, S)
聲明式環(huán)境記錄項(xiàng)的 GetBindingValue 具體方法簡單地返回名稱為參數(shù) N 的綁定的值。方法調(diào)用時(shí),該綁定必須存在。如果 S 的值為 true 且該綁定是一個(gè)未初始化的不可變綁定,則拋出一個(gè) ReferenceError 異常。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
執(zhí)行斷言:envRec 必須有 N 的綁定。
如果 envRec 中 N 的綁定是一個(gè)未初始化的不可變綁定,則:
如果 S 為 false,返回 undefined,否則拋出一個(gè) ReferenceError 異常。
否則返回 envRec 中與 N 綁定的值。
DeleteBinding(N)
聲明式環(huán)境記錄項(xiàng)的 DeleteBinding 具體方法只能刪除顯示指定可被刪除的那些綁定。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
如果 envRec 不包含名稱為 N 的綁定,返回 true。
如果 envRec 中 N 的綁定不能刪除,返回 false。
移除 envRec 中 N 的綁定。
返回 true。
ImplicitThisValue()
聲明式環(huán)境記錄項(xiàng)永遠(yuǎn)將 undefined 作為其 ImplicitThisValue 返回。
返回 undefined。
CreateImmutableBinding(N)
聲明式環(huán)境記錄項(xiàng)的 CreateImmutableBinding 具體方法會(huì)創(chuàng)建一個(gè)不可變綁定,其名稱為 N 且初始化其值為 undefined。調(diào)用方法時(shí),該環(huán)境記錄項(xiàng)中不得存在 N 的綁定。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
執(zhí)行斷言:envRec 不存在 N 的綁定。
在 envRec 中為 N 創(chuàng)建一個(gè)不可變綁定,并記錄為未初始化。
InitializeImmutableBinding(N, V)
聲明式環(huán)境記錄項(xiàng)的 InitializeImmutableBinding 具體方法用于將當(dāng)前名稱為參數(shù) N 的綁定的值修改為參數(shù) V 指定的值。方法調(diào)用時(shí),必須存在 N 對(duì)應(yīng)的未初始化的不可變綁定。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
執(zhí)行斷言:envRec 存在一個(gè)與 N 對(duì)應(yīng)的未初始化的不可變綁定。
在 envRec 中將 N 的綁定的值設(shè)置為 V。
在 envRec 中將 N 的不可變綁定記錄為已初始化。
對(duì)象式環(huán)境記錄項(xiàng)
每一個(gè)對(duì)象式環(huán)境記錄項(xiàng)都有一個(gè)關(guān)聯(lián)的對(duì)象,這個(gè)對(duì)象被稱作綁定對(duì)象。對(duì)象式環(huán)境記錄項(xiàng)直接將一系列標(biāo)識(shí)符與其綁定對(duì)象的屬性名稱建立一一對(duì)應(yīng)關(guān)系。不符合 標(biāo)識(shí)符使用。無論是對(duì)象自身的,還是繼承的屬性都會(huì)作為綁定,無論該屬性的 [[Enumerable]] 特性的值是什么。由于對(duì)象的屬性可以動(dòng)態(tài)的增減,因此對(duì)象式環(huán)境記錄項(xiàng)所綁定的標(biāo)識(shí)符集合也會(huì)隱匿地變化,這是增減綁定對(duì)象的屬性而產(chǎn)生的副作用。通過以上描述的副作用而建立的綁定,均被視為可變綁定,即使該綁定對(duì)應(yīng)的屬性的 [[Writable]] 特性的值為 false。對(duì)象式環(huán)境記錄項(xiàng)沒有不可變綁定。
對(duì)象式環(huán)境記錄項(xiàng)可以通過配置的方式,將其綁定對(duì)象合為函數(shù)調(diào)用時(shí)的隱式 this 對(duì)象的值。這一功能用于規(guī)范 對(duì)象式環(huán)境記錄項(xiàng)中布爾類型的 provideThis 值控制,默認(rèn)情況下,provideThis 的值為 false。
環(huán)境記錄項(xiàng)定義的方法的具體行為將由以下算法給予描述。
HasBinding(N)
對(duì)象式環(huán)境記錄項(xiàng)的 HasBinding 具體方法判斷其關(guān)聯(lián)的綁定對(duì)象是否有名為 N 的屬性:
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
令 bindings 為 envRec 的綁定對(duì)象。
以 N 為屬性名,調(diào)用 bindings 的 [[HasProperty]] 內(nèi)部方法,并返回調(diào)用的結(jié)果。
CreateMutableBinding(N, D)
對(duì)象式環(huán)境記錄項(xiàng)的 CreateMutableBinding具體方法會(huì)在其關(guān)聯(lián)的綁定對(duì)象上創(chuàng)建一個(gè)名稱為 N 的屬性,并初始化其值為 undefined。調(diào)用方法時(shí),綁定對(duì)象不得包含名稱為 N 的屬性。如果調(diào)用方法時(shí)提供了布爾類型的參數(shù) D 且其值為 true,則設(shè)置新創(chuàng)建的屬性的 [[Configurable]] 特性的值為 true,否則設(shè)置為 false。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
令 bindings 為 envRec 的綁定對(duì)象。
執(zhí)行斷言:以 N 為屬性名,調(diào)用 bindings 的 [[HasProperty]] 內(nèi)部方法,調(diào)用的結(jié)果為 false。
如果 D 的值為 true,則令 configValue 的值為 true,否則令 configValue 的值為 false。
以 N、屬性描述符 {[[Value]]:undefined, [[Writable]]: true, [[Enumerable]]: true , [[Configurable]]: configValue} 和布爾值 true 為參數(shù),調(diào)用 bindings 的 [[DefineOwnProperty]] 內(nèi)部方法。
SetMutableBinding(N, V, S)
對(duì)象式環(huán)境記錄項(xiàng)的 SetMutableBinding 具體方法會(huì)嘗試設(shè)置其關(guān)聯(lián)的綁定對(duì)象中名為 N 的屬性的值為 V。方法調(diào)用時(shí),綁定對(duì)象中應(yīng)當(dāng)存在該屬性,如果該屬性不存在或?qū)傩圆豢蓪?#xff0c;則根據(jù) S 參數(shù)的值來執(zhí)行錯(cuò)誤處理。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
令 bindings 為 envRec 的綁定對(duì)象
以 N、V 和 S 為參數(shù),調(diào)用 bindings 的 [[Put]] 內(nèi)部方法。
GetBindingValue(N, S)
對(duì)象式環(huán)境記錄項(xiàng)的 GetBindingValue 具體方法返回其關(guān)聯(lián)的綁定對(duì)象中名為 N 的屬性的值。方法調(diào)用時(shí),綁定對(duì)象中應(yīng)當(dāng)存在該屬性,如果該屬性不存在,則方法的返回值由 S 參數(shù)決定:
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
令 bindings 為 envRec 的綁定對(duì)象
以 N 為屬性名,調(diào)用 bindings 的 [[HasProperty]] 內(nèi)部方法,并令 value 為調(diào)用的結(jié)果。
如果 value 的值為 false,則:
如果 S 的值為 false,則返回 undefined,否則拋出一個(gè) ReferenceError 異常。
以 N 為參數(shù),調(diào)用 bindings 的 [[Get]] 內(nèi)部方法,并返回調(diào)用的結(jié)果。
DeleteBinding(N)
對(duì)象式環(huán)境記錄項(xiàng)的 DeleteBinding 具體方法只能用于刪除其關(guān)聯(lián)的綁定對(duì)象上 [[Configurable]] 特性的值為 true 的屬性所對(duì)應(yīng)的綁定。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的聲明式環(huán)境記錄項(xiàng)。
令 bindings 為 envRec 的綁定對(duì)象
以 N 和布爾值 false 為參數(shù),調(diào)用 bindings 的 [[Delete]] 內(nèi)部方法。
ImplicitThisValue()
對(duì)象式環(huán)境記錄項(xiàng)的 ImplicitThisValue 通常返回 undefined,除非其 provideThis 標(biāo)識(shí)的值為 true。
令 envRec 為函數(shù)調(diào)用時(shí)對(duì)應(yīng)的對(duì)象式環(huán)境記錄項(xiàng)。
如果 envRec 的 provideThis 標(biāo)識(shí)的值為 true,返回 envRec 的綁定對(duì)象。
否則返回 undefined。
詞法環(huán)境的運(yùn)算
在本標(biāo)準(zhǔn)中,以下抽象運(yùn)算將被用于操作環(huán)境記錄項(xiàng):
GetIdentifierReference(lex, name, strict)
當(dāng)調(diào)用 GetIdentifierReference 抽象運(yùn)算時(shí),需要指定一個(gè)詞法環(huán)境 lex,一個(gè)標(biāo)識(shí)符字符串 name 以及一個(gè)布爾型標(biāo)識(shí) strict。lex 的值可以為 null。當(dāng)調(diào)用該運(yùn)算時(shí),按以下步驟進(jìn)行:
如果 lex 的值為 null,則:
返回一個(gè)類型為引用的對(duì)象,其基值為 undefined,引用的名稱為 name,嚴(yán)格模式標(biāo)識(shí)的值為 strict。
令 envRec 為 lex 的環(huán)境數(shù)據(jù)。
以 name 為參數(shù) N,調(diào)用 envRec 的 HasBinding(N) 具體方法,并令 exists 為調(diào)用的結(jié)果。
如果 exists 為 true,則:
返回一個(gè)類型為引用的對(duì)象,其基值為 envRec,引用的名稱為 name,嚴(yán)格模式標(biāo)識(shí)的值為 strict。
否則:
令 outer 為 lex 的外部環(huán)境引用。
以 outer、name 和 strict 為參數(shù),調(diào)用 GetIdentifierReference,并返回調(diào)用的結(jié)果。
NewDeclarativeEnvironment(E)
當(dāng)調(diào)用 NewDeclarativeEnvironment 抽象運(yùn)算時(shí),需指定一個(gè)詞法環(huán)境 E,其值可以為 null,此時(shí)按以下步驟進(jìn)行:
令 env 為一個(gè)新建的詞法環(huán)境。
令 envRec 為一個(gè)新建的聲明式環(huán)境數(shù)據(jù),該環(huán)境數(shù)據(jù)不包含任何綁定。
令 env 的環(huán)境數(shù)據(jù)為 envRec。
令 env 的外部詞法環(huán)境引用至 E。
返回 env。
NewObjectEnvironment(O, E)
當(dāng)調(diào)用 NewObjectEnvironment 抽象運(yùn)算時(shí),需指定一個(gè)對(duì)象 O 及一
個(gè)詞法環(huán)境 E(其值可以為 null),此時(shí)按以下步驟進(jìn)行:
令 env 為一個(gè)新建的詞法環(huán)境。
令 envRec 為一個(gè)新建的對(duì)象環(huán)境數(shù)據(jù),該環(huán)境數(shù)據(jù)包含 O 作為綁定對(duì)象。
令 env 的環(huán)境數(shù)據(jù)為 envRec。
令 env 的外部詞法環(huán)境引用至 E。
返回 env。
全局環(huán)境
全局環(huán)境是一個(gè)唯一的詞法環(huán)境,它在任何 ECMA 腳本的代碼執(zhí)行前創(chuàng)建。全局環(huán)境的環(huán)境數(shù)據(jù)是一個(gè)對(duì)象環(huán)境數(shù)據(jù),該環(huán)境數(shù)據(jù)使用全局對(duì)象(15.1)作為綁定對(duì)象。全局環(huán)境的外部環(huán)境引用為 null。
在 ECMA 腳本的代碼執(zhí)行過程中,可能會(huì)向全局對(duì)象添加額外的屬性,也可能修改其初始屬性的值。
執(zhí)行環(huán)境
當(dāng)控制器轉(zhuǎn)入 ECMA 腳本的可執(zhí)行代碼時(shí),控制器會(huì)進(jìn)入一個(gè)執(zhí)行環(huán)境。當(dāng)前活動(dòng)的多個(gè)執(zhí)行環(huán)境在邏輯上形成一個(gè)棧結(jié)構(gòu)。該邏輯棧的最頂層的執(zhí)行環(huán)境稱為當(dāng)前運(yùn)行的執(zhí)行環(huán)境。任何時(shí)候,當(dāng)控制器從當(dāng)前運(yùn)行的執(zhí)行環(huán)境相關(guān)的可執(zhí)行代碼轉(zhuǎn)入與該執(zhí)行環(huán)境無關(guān)的可執(zhí)行代碼時(shí),會(huì)創(chuàng)建一個(gè)新的執(zhí)行環(huán)境。新建的這個(gè)執(zhí)行環(huán)境會(huì)推入棧中,成為當(dāng)前運(yùn)行的執(zhí)行環(huán)境。
執(zhí)行環(huán)境包含所有用于追蹤與其相關(guān)的代碼的執(zhí)行進(jìn)度的狀態(tài)。精確地說,每個(gè)執(zhí)行環(huán)境包含如 表19 列出的組件。
表19 — 執(zhí)行環(huán)境的狀態(tài)組件
組件
作用目的
詞法環(huán)境組件
指定一個(gè)詞法環(huán)境對(duì)象,用于解析該執(zhí)行環(huán)境內(nèi)的代碼創(chuàng)建的標(biāo)識(shí)符引用。
變量環(huán)境組件
this 綁定
指定該執(zhí)行環(huán)境內(nèi)的 ECMA 腳本代碼中 this 關(guān)鍵字所關(guān)聯(lián)的值。
其中執(zhí)行環(huán)境的詞法環(huán)境組件和變量環(huán)境組件始終為詞法環(huán)境對(duì)象。當(dāng)創(chuàng)建一個(gè)執(zhí)行環(huán)境時(shí),其詞法環(huán)境組件和變量環(huán)境組件最初是同一個(gè)值。在該執(zhí)行環(huán)境相關(guān)聯(lián)的代碼的執(zhí)行過程中,變量環(huán)境組件永遠(yuǎn)不變,而詞法環(huán)境組件有可能改變。
在本標(biāo)準(zhǔn)中,通常情況下,只有正在運(yùn)行的執(zhí)行環(huán)境(執(zhí)行環(huán)境棧里的最頂層對(duì)象)會(huì)被算法直接修改。因此當(dāng)遇到“詞法環(huán)境組件”、“變量環(huán)境組件”、“this 綁定組件”這三個(gè)術(shù)語時(shí),指的是正在運(yùn)行的執(zhí)行環(huán)境的對(duì)應(yīng)組件。
執(zhí)行環(huán)境是一個(gè)純粹的標(biāo)準(zhǔn)機(jī)制,并不代表任何 ECMA 腳本實(shí)現(xiàn)的工件。在 ECMA 腳本程序中是不可能訪問到執(zhí)行環(huán)境的。
標(biāo)識(shí)符解析
標(biāo)識(shí)符解析是指使用正在運(yùn)行的執(zhí)行環(huán)境中的詞法環(huán)境組件,通過一個(gè) :
令 env 為正在運(yùn)行的執(zhí)行環(huán)境的 詞法環(huán)境組件。
如果正在解釋執(zhí)行的語法產(chǎn)生式處在嚴(yán)格模式下的代碼中,則僅 strict 的值為 true,否則令 strict 的值為 false。
解釋執(zhí)行一個(gè)標(biāo)識(shí)符得到的結(jié)果必定是引用類型的對(duì)象,且其引用名屬性的值與
建立執(zhí)行環(huán)境
解釋執(zhí)行全局代碼或使用 eval 函數(shù)輸入的代碼會(huì)創(chuàng)建并進(jìn)入一個(gè)新的執(zhí)行環(huán)境。每次調(diào)用 ECMA 腳本代碼定義的函數(shù)(13.2.1)也會(huì)建立并進(jìn)入一個(gè)新的執(zhí)行環(huán)境,即便函數(shù)是自身遞歸調(diào)用的。每一次 return 都會(huì)退出一個(gè)執(zhí)行環(huán)境。拋出異常也可退出一個(gè)或多個(gè)執(zhí)行環(huán)境。
當(dāng)控制流進(jìn)入一個(gè)執(zhí)行環(huán)境時(shí),會(huì)設(shè)置該執(zhí)行環(huán)境的 this 綁定組件,定義變量環(huán)境和初始詞法環(huán)境,并執(zhí)行聲明式綁定初始化過程。以上這些步驟的嚴(yán)格執(zhí)行方式由進(jìn)入的代碼的類型決定。
進(jìn)入全局代碼
當(dāng)控制流進(jìn)入全局代碼的執(zhí)行環(huán)境時(shí),執(zhí)行以下步驟:
按 10.4.1.1 描述的方案,使用全局代碼初始化執(zhí)行環(huán)境。
初始化全局執(zhí)行環(huán)境
以下步驟描述 ECMA 腳本的全局執(zhí)行環(huán)境 C 的創(chuàng)建過程:
進(jìn)入 eval 代碼
當(dāng)控制流進(jìn)入 eval代碼 的執(zhí)行環(huán)境時(shí),執(zhí)行以下步驟:
如果沒有調(diào)用環(huán)境,或者 eval代碼 并非通過直接調(diào)用 eval 函數(shù)來解釋執(zhí)行的 ,則
按(10.4.1.1)描述的初始化全局執(zhí)行環(huán)境的方案,以 eval代碼 作為 C 來初始化執(zhí)行環(huán)境。
如果 eval 代碼是嚴(yán)格模式下的代碼,則
令 strictVarEnv 為以詞法環(huán)境為參數(shù)調(diào)用 NewDeclarativeEnvironment 得到的結(jié)果。
設(shè)置 詞法環(huán)境組件 為 strictVarEnv。
設(shè)置 變量環(huán)境組件 為 strictVarEnv。
嚴(yán)格模式下的限制
如果調(diào)用環(huán)境的代碼或 eval 代碼是嚴(yán)格模式下的代碼,則 eval 代碼不能在調(diào)用環(huán)境的 變量環(huán)境組件 中初始化變量及函數(shù)綁定。與之相對(duì)的,變量及函數(shù)綁定將在一個(gè)新的 變量環(huán)境組件 中被初始化,該 變量環(huán)境組件 僅可被 eval 代碼訪問。
進(jìn)入函數(shù)代碼
當(dāng)控制流根據(jù)一個(gè)函數(shù)對(duì)象 F、調(diào)用者提供的 thisArg 以及調(diào)用者提供的 argumentList,進(jìn)入函數(shù)代碼的執(zhí)行環(huán)境時(shí),執(zhí)行以下步驟:
否則如果 thisArg 是 null 或 undefined,則設(shè) this 綁定 為全局對(duì)象。
否則如果 Type(thisArg) 的結(jié)果不為 Object,則設(shè) this 綁定 為 ToObject(thisArg)。
否則設(shè) this 綁定 為 thisArg。
設(shè) 詞法環(huán)境組件 為 localEnv。
設(shè) 變量環(huán)境組件 為 localEnv。
令 code 為 F 的 [[Code]] 內(nèi)部屬性的值。
按 10.5 描述的方案,使用函數(shù)代碼 code 和 argumentList 執(zhí)行聲明式綁定初始化化步驟。
聲明式綁定初始化
每個(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ù)也同樣會(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)境記錄項(xiàng)。
如果 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 f:
以 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)部方法。
否則如果 IsAccessorDescriptor(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è) d 執(zhí)行:
令 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 具體方法。
創(chuàng)建 Arguments 對(duì)象
當(dāng)控制器進(jìn)入到函數(shù)代碼的執(zhí)行環(huán)境時(shí),將創(chuàng)建一個(gè) arguments 對(duì)象(透過 10.5 指定的方式),除非它作為標(biāo)識(shí)符 arguments 出現(xiàn)在該函數(shù)的形參列表中,或者是該函數(shù)代碼內(nèi)部的變量聲明標(biāo)識(shí)符或函數(shù)聲明標(biāo)識(shí)符。
arguments 對(duì)象通過調(diào)用抽象方法 CreateArgumentsObject 創(chuàng)建,調(diào)用時(shí)將以下參數(shù)傳入:func、names、args、env、strict。將要執(zhí)行的函數(shù)對(duì)象作為 func 參數(shù),將該函數(shù)的所有形參名加入一個(gè)列表,稱為 names 參數(shù),將所有傳給內(nèi)部方法 [[Call]] 的實(shí)際參數(shù),稱為 args 參數(shù),將該函數(shù)代碼的變量環(huán)境稱為 env 參數(shù),將該函數(shù)代碼是否為嚴(yán)格代碼作為 strict 參數(shù)。當(dāng) CreateArgumentsObject 調(diào)用時(shí),按照以下步驟執(zhí)行:
令 len 為參數(shù) args 的元素個(gè)數(shù)。
令 obj 為一個(gè)新建的 ECMAScript 對(duì)象。
按照 8.12 章節(jié)中的規(guī)范去設(shè)定 obj 對(duì)象的所有內(nèi)部方法。
將 obj 對(duì)象的內(nèi)部屬性 [[Class]] 設(shè)置為 "Arguments"。
令 Object 為標(biāo)準(zhǔn)的內(nèi)置對(duì)象的構(gòu)造函數(shù)(15.2.2)。
將 obj 對(duì)象的內(nèi)部屬性 [[Prototype]] 設(shè)置為標(biāo)準(zhǔn)的內(nèi)置對(duì)象的原型對(duì)象。
調(diào)用 obj 的內(nèi)部方法 [[DefineOwnProperty]],將 "length" 傳遞進(jìn)去,屬性描述符為:{[[Value]]: len, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true},參數(shù)為 false。
令 map 為表達(dá)式 new Object() 創(chuàng)建的對(duì)象,就是名為 Object 的標(biāo)準(zhǔn)的內(nèi)置構(gòu)造函數(shù)。
令 mappedNames 為一個(gè)空的列表。
令 indx = len - 1
當(dāng) indx >= 0 的時(shí)候,重復(fù)此過程:
令 val 為 args(維度從 0 開始的列表)的第 indx 維度所在的元素。
調(diào)用 obj 的內(nèi)部方法 [[DefineOwnProperty]],將 ToString(indx) 傳遞進(jìn)去,屬性描述符為:{[[Value]]: val, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true},參數(shù)為 false。
如果 indx 小于 names 的元素個(gè)數(shù),則
令 name 為 names(維度從 0 開始的列表)的第 indx 維度所在的元素。
如果 strict 值為 false,且 name 不是一個(gè) mappedNames 元素,則
將 name 添加到 mappedNames 列表中,作為它的一個(gè)元素
令 g 為調(diào)用抽象操作 MakeArgGetter 的結(jié)果,其參數(shù)為 name 和 env。
令 p 為調(diào)用抽象操作 MakeArgSetter 的結(jié)果,其參數(shù)為 name 和 env。
調(diào)用 map 對(duì)象的內(nèi)部方法 [[DefineOwnProperty]],將 ToString(indx) 傳遞進(jìn)去,屬性描述符為:{[[Set]]: p, [[Get]]: g, [[Configurable]]: true},參數(shù)為 false。
令 indx = indx - 1
如果 strict 值為 false,則
調(diào)用 obj 對(duì)象的內(nèi)部方法 [[DefineOwnProperty]],將 "callee" 傳遞進(jìn)去,屬性描述符為:{[[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true},參數(shù)為 false。
否則,strict 值為 true,那么
調(diào)用 obj 對(duì)象的內(nèi)部方法 [[DefineOwnProperty]],將 "caller" 傳遞進(jìn)去,屬性描述符為:{[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},參數(shù)為 false。
調(diào)用 obj 對(duì)象的內(nèi)部方法 [[DefineOwnProperty]],將 "callee" 傳遞進(jìn)去,屬性描述符為:{[[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},參數(shù)為 false。
返回 obj。
抽象操作 MakeArgGetter 以字符串 name 和環(huán)境記錄 env 作為參數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)函數(shù)對(duì)象,當(dāng)執(zhí)行完后,會(huì)返回在 env 中綁定的 name 的值。執(zhí)行步驟如下:
令 body 為字符 "return "、name、";" 的連接字符串。
返回一個(gè)按照 13.2 章節(jié)中描述的方式創(chuàng)建的函數(shù)對(duì)象,它不需要形參列表,以 body 作為它的 env 作為它的 Scope,并且 strict 值為 true。
抽象操作 MakeArgSetter 以字符串 name 和環(huán)境記錄 env 作為參數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)函數(shù)對(duì)象,當(dāng)執(zhí)行完后,會(huì)給在 env 中綁定的 name 設(shè)置一個(gè)值。執(zhí)行步驟如下:
令 param 為 name 和字符串 "_arg" 的連接字符串。
令 body 為字符串 "=;";將 替換為 name 的值,將 替換為 param 的值。
返回一個(gè)按照 13.2 章節(jié)中描述的方式創(chuàng)建的函數(shù)對(duì)象,以一個(gè)只包含字符串 param 的列表作為它的形參,以 body 作為它的函數(shù)體(env 作為它的 Scope,并且 strict 值為 true。
當(dāng) arguments 對(duì)象的內(nèi)部方法 [[Get]] 在一個(gè)非嚴(yán)格模式下帶有形參的函數(shù)中,在一個(gè)屬性名為 P 的條件下被調(diào)用時(shí),其執(zhí)行步驟如下:
令 map 為 arguments 對(duì)象的內(nèi)部屬性 [[ParameterMap]]。
令 isMapped 為 map 對(duì)象的內(nèi)部方法 [[GetOwnPropery]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
如果 isMapped 值為 undefined,則
令 v 為 arguments 對(duì)象的內(nèi)部默認(rèn)的 [[Get]] 方法(8.12.3),傳入?yún)?shù) P 的執(zhí)行結(jié)果。
如果 P 為 "caller",且 v 為嚴(yán)格模式下的 Function 對(duì)象,則拋出一個(gè) TypeError 的異常。
返回 v。
否則,map 包含一個(gè) P 的形參映射表。
返回 map 對(duì)象的內(nèi)部方法 [[Get]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
當(dāng) arguments 對(duì)象的內(nèi)部方法 [[GetOwnProperty]] 在一個(gè)非嚴(yán)格模式下帶有形參的函數(shù)中,在一個(gè)屬性名為 P 的條件下被調(diào)用時(shí),其執(zhí)行步驟如下:
令 desc 為 arguments 對(duì)象的內(nèi)部方法 [[GetOwnProperty]](8.12.1)傳入?yún)?shù) P 的執(zhí)行結(jié)果。
如果 desc 為 undefined,返回 desc。
令 map 為 arguments 對(duì)象內(nèi)部屬性 [[ParameterMap]] 的值。
令 isMapped 為 map 對(duì)象的內(nèi)部方法 [[GetOwnPropery]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
如果 isMapped 的值不是 undefined,則
將 desc.[[Value]] 的值設(shè)置為 map 對(duì)象的內(nèi)部方法 [[Get]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
返回 desc。
當(dāng) arguments 對(duì)象的內(nèi)部方法 [[DefineOwnProperty]] 在一個(gè)非嚴(yán)格模式下帶有形參的函數(shù)中,在一個(gè)屬性名為 P,屬性描述符為 Desc,布爾標(biāo)志為 Throw 的條件下被調(diào)用時(shí),其執(zhí)行步驟如下:
令 map 為 arguments 對(duì)象的內(nèi)部屬性 [[ParameterMap]] 的值。
令 isMapped 為 map 對(duì)象的內(nèi)部方法 [[GetOwnPropery]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
令 allowed 為 arguments 對(duì)象的內(nèi)部方法 [[DefineOwnPropery]](8.12.9)傳入?yún)?shù) P、Desc、false 的執(zhí)行結(jié)果。
如果 allowed 為 false,則
如果 Throw 為 true,則拋出一個(gè) TypeError 的異常,否則,返回 false。
如果 isMapped 的值不為 undefined,則
如果 IsIsAccessorDescriptor(Desc) 為 true,則
調(diào)用 map 對(duì)象的內(nèi)部方法 [[Delete]],傳入 P 和 false 作為參數(shù)。
否則
如果 Desc.[[Value]] 存在,則
調(diào)用 map 對(duì)象的內(nèi)部方法 [[Put]],傳入 P、Desc.[[Value]] 和 Throw 作為參數(shù)。
如果 Desc.[[Writable]] 存在,且其值為 false,則
調(diào)用 map 對(duì)象的內(nèi)部方法 [[Delete]],傳入 P 和 false 作為參數(shù)。
返回 true。
當(dāng) arguments 對(duì)象的內(nèi)部方法 [[Delete]] 在一個(gè)非嚴(yán)格模式下帶有形參的函數(shù)中,在一個(gè)屬性名為 P,布爾標(biāo)志為 Throw 的條件下被調(diào)用時(shí),其執(zhí)行步驟如下:
令 map 為 arguments 對(duì)象的內(nèi)部屬性 [[ParameterMap]] 的值。
令 isMapped 為 map 對(duì)象的內(nèi)部方法 [[GetOwnPropery]] 傳入?yún)?shù) P 的執(zhí)行結(jié)果。
令 result 為 arguments 對(duì)象的內(nèi)部方法 [[Delete]](8.12.7)傳入?yún)?shù) P 和 Throw 的執(zhí)行結(jié)果。
如果 result 為 true,且 isMapped 不為 undefined,則
調(diào)用 map 對(duì)象的內(nèi)部方法 [[Delete]],傳入 P 和 false 作為參數(shù)。
返回 result。
注: 非嚴(yán)格模式下的函數(shù),arguments 對(duì)象以數(shù)組索引(參見 15.4 的定義)作為數(shù)據(jù)屬性的命名,其數(shù)字名字的值少于對(duì)應(yīng)的函數(shù)對(duì)象初始時(shí)的形參數(shù)量,它們與綁定在該函數(shù)執(zhí)行環(huán)境中對(duì)應(yīng)的參數(shù)共享值。這意味著,改變?cè)搶傩詫⒏淖冞@些對(duì)應(yīng)的、綁定的參數(shù)的值,反之亦然。如果其中一個(gè)屬性被刪除然后再對(duì)其重定義,或者其中一個(gè)屬性在某個(gè)訪問器屬性內(nèi)部被更改,則這種對(duì)應(yīng)關(guān)系將被打破。嚴(yán)格模式下的函數(shù),arguments 對(duì)象的屬性值就是傳入該函數(shù)的實(shí)際參數(shù)的簡單拷貝,它們與形參之間的值不存在動(dòng)態(tài)的聯(lián)動(dòng)關(guān)系。
注: ParameterMap 對(duì)象和它的屬性值被作為說明 arguments 對(duì)象對(duì)應(yīng)綁定參數(shù)的裝置。ParameterMap 對(duì)象和它的屬性值對(duì)象不能直接被 ECMAScript 代碼訪問。作為 ECMAScript 的實(shí)現(xiàn),不需要實(shí)際創(chuàng)建或使用這些對(duì)象去實(shí)現(xiàn)指定的語義。
注: 嚴(yán)格模式下函數(shù)的 Arguments 對(duì)象定義的非可配置的訪問器屬性,"caller" 和 "callee",在它們被訪問時(shí),將拋出一個(gè) TypeError 的異常。在非嚴(yán)格模式下,"callee" 屬性具有非常明確的意義,"caller" 屬性有一個(gè)歷史問題,它是否被提供,視為一個(gè)由實(shí)作環(huán)境決定的,在具體的 ECMAScript 實(shí)作進(jìn)行擴(kuò)展。在嚴(yán)格模式下對(duì)這些屬性的定義的出現(xiàn)是為了確保它們倆誰也不能在規(guī)范的 ECMAScript 實(shí)作中以任何方式被定義。
總結(jié)
以上是生活随笔為你收集整理的html代码在线运行环境,ES5/可执行代码与执行环境的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鸿蒙手机系统开发大会,鸿蒙OS+EMUI
- 下一篇: html画圆中有个正方形,这样画圆内接正