javascript執(zhí)行上下文、變量對(duì)象實(shí)例分析
本文實(shí)例講述了javascript執(zhí)行上下文、變量對(duì)象。分享給大家供大家參考,具體如下:
突然看到一篇遠(yuǎn)在2010年的老文,作者以章節(jié)的形式向我們介紹了ECMA-262-3的部分內(nèi)容,主要涉及到執(zhí)行上下文、變量對(duì)象、作用域、this等語(yǔ)言細(xì)節(jié)。內(nèi)容短小而精悍,文風(fēng)直白而嚴(yán)謹(jǐn),讀完有酣暢淋漓、醍醐灌頂之感,強(qiáng)烈推薦?。?!
原文鏈接:這里
本想翻譯成文,原來(lái)早已有人做了,這里。真生不逢時(shí),何其遺憾??!
做個(gè)筆記,聊慰我心。
執(zhí)行上下文 ExecutionContext
每當(dāng)控制器(control)轉(zhuǎn)換到ECMAScript可執(zhí)行代碼時(shí),都會(huì)創(chuàng)建并進(jìn)入到一個(gè)可執(zhí)行上下文。
一段簡(jiǎn)短的句子,卻包含著豐富的內(nèi)容:
- 控制器:即
js引擎 - 轉(zhuǎn)換:從一段可執(zhí)行代碼跳轉(zhuǎn)到另一段可執(zhí)行代碼
- 可執(zhí)行代碼:全局代碼、函數(shù)代碼、
eval代碼(分別對(duì)應(yīng)三種作用域) - 執(zhí)行上下文:是一個(gè)抽象的概念,ECMA-262標(biāo)準(zhǔn)用這個(gè)概念同可執(zhí)行代碼(executable code)概念進(jìn)行區(qū)分
執(zhí)行上下文在邏輯上組成一個(gè)堆棧。堆棧底部永遠(yuǎn)都是全局上下文(global context),堆棧頂部是當(dāng)前/活動(dòng)的執(zhí)行上下文(activeExecutionContext)。堆棧在EC類(lèi)型的變量(various kingds of EC)被推入或彈出的同時(shí)被修改。
例如,我們可以定義一個(gè)數(shù)組來(lái)模擬執(zhí)行上下文堆棧:
ECStack = [ globalContext, <foo> functionContext ]
變量對(duì)象 VariableObject
變量對(duì)象(VO)作為執(zhí)行上下文的一個(gè)屬性存在,它存儲(chǔ)下列內(nèi)容:
- 所有變量聲明 (var, VariableDeclaration)
- VO的一個(gè)屬性,這個(gè)屬性由變量名稱(chēng)和undefined值組成;如果變量名稱(chēng)跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會(huì)干擾已經(jīng)存在的這類(lèi)屬性。
- 函數(shù)聲明 (FunctionDeclaration, 縮寫(xiě)為FD)
- VO的一個(gè)屬性,這個(gè)屬性由一個(gè)函數(shù)對(duì)象(function-object)的名稱(chēng)和值組成;如果變量對(duì)象已經(jīng)存在相同名稱(chēng)的屬性,則完全替換這個(gè)屬性。
- 以及函數(shù)的形參
- VO的一個(gè)屬性,這個(gè)屬性由一個(gè)形式參數(shù)的名稱(chēng)和值組成;如果沒(méi)有對(duì)應(yīng)傳遞實(shí)際參數(shù),那么這個(gè)屬性就由形式參數(shù)的名稱(chēng)和undefined值組成;
VO = {
// context data (var, FD, function arguments)
}
當(dāng)我們聲明一個(gè)變量或一個(gè)函數(shù)的時(shí)候,同時(shí)還用變量的名稱(chēng)和值在VO里創(chuàng)建了一個(gè)新的屬性。
例如:
var m = 30;
function test(a,b) {
var c = 20
function d() {}
var e = function _e() {};
}
test(10)
當(dāng)進(jìn)入“test”函數(shù)的上下文時(shí)(傳遞參數(shù)10),AO如下:
AO(test) = {
a: 10,
b: undefined,
c: undefined,
d: <reference to FunctionDeclaration "d">
e: undefined
};
test執(zhí)行到最后時(shí),對(duì)應(yīng)此刻上下文堆棧:
ECStack = [
globalContext: {
VO: {
m: 30,
test:
}
},
test functionContext: {
VO: {
a: 10,
b: undefined,
c: 20,
d: <reference to FunctionDeclaration "d">,
e: <reference to FunctionDeclaration "_e">
}
}
]
關(guān)于變量
通常,各類(lèi)文章和JavaScript相關(guān)的書(shū)籍都聲稱(chēng):“不管是使用var關(guān)鍵字(在全局上下文)還是不使用var關(guān)鍵字(在任何地方),都可以聲明一個(gè)變量”。請(qǐng)記住,這絕對(duì)是謠傳:任何時(shí)候,變量只能通過(guò)使用var關(guān)鍵字才能聲明。
讓我們通過(guò)下面的實(shí)例看看具體的區(qū)別吧:
alert(a); // undefined alert(b); // "b" is not defined b = 10; var a = 20;
所有根源仍然是VO和它的修改階段(進(jìn)入上下文階段和執(zhí)行代碼階段):
VO = {
a: undefined
};
我們可以看到,因?yàn)椤癰”不是一個(gè)變量,所以在這個(gè)階段根本就沒(méi)有“b”,“b”將只在執(zhí)行代碼階段才會(huì)出現(xiàn)(但是在我們這個(gè)例子里,還沒(méi)有到那就已經(jīng)出錯(cuò)了)。
讓我們改變一下例子代碼:
alert(a); // undefined, we know why b = 10; alert(b); // 10, created at code execution var a = 20; alert(a); // 20, modified at code execution
關(guān)于變量,還有一個(gè)重要的知識(shí)點(diǎn)。變量相對(duì)于簡(jiǎn)單屬性來(lái)說(shuō),變量有一個(gè)特性(attribute):{DontDelete},這個(gè)特性的含義就是不同通過(guò)delete操作符直接刪除變量屬性。
a = 10; alert(window.a); // 10 alert(delete a); // true alert(window.a); // undefined var b = 20; alert(window.b); // 20 alert(delete b); // false alert(window.b); // still 20
2018-8-2-再看執(zhí)行上下文、變量對(duì)象
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
微信小程序?qū)崿F(xiàn)發(fā)送短信驗(yàn)證碼倒計(jì)時(shí)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)發(fā)送短信驗(yàn)證碼倒計(jì)時(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
JS+CSS實(shí)現(xiàn)消息的點(diǎn)擊展示和隱藏(H5端)
在 H5 端,我們經(jīng)常需要實(shí)現(xiàn)類(lèi)似于點(diǎn)擊按鈕來(lái)展示或隱藏消息的功能,以下是一個(gè)使用 CSS 和 JavaScript(配合 Vue.js)來(lái)實(shí)現(xiàn)這個(gè)效果的簡(jiǎn)單示例,需要的朋友可以參考下2023-10-10
JavaScript hasOwnProperty() 函數(shù)實(shí)例詳解
hasOwnProperty()函數(shù)用于指示一個(gè)對(duì)象自身(不包括原型鏈)是否具有指定名稱(chēng)的屬性。下面通過(guò)本文給大家分享JavaScript hasOwnProperty() 函數(shù)實(shí)例講解,感興趣的朋友一起看看吧2017-08-08
Javascript的數(shù)組與字典用法與遍歷對(duì)象的技巧
Javascript 的數(shù)組Array,既是一個(gè)數(shù)組,也是一個(gè)字典(Dictionary)。先舉例看看數(shù)組的用法2012-11-11
js實(shí)現(xiàn)拖動(dòng)模態(tài)框
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)拖動(dòng)模態(tài)框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
JS使用面向?qū)ο蠹夹g(shù)實(shí)現(xiàn)的tab選項(xiàng)卡效果示例
這篇文章主要介紹了JS使用面向?qū)ο蠹夹g(shù)實(shí)現(xiàn)的tab選項(xiàng)卡效果,結(jié)合具體實(shí)例形式分析了js面向?qū)ο蠹夹g(shù)與tab選項(xiàng)卡功能的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02
如何使用json在前后臺(tái)進(jìn)行數(shù)據(jù)傳輸實(shí)例介紹
需要把這些輸入寫(xiě)入數(shù)據(jù)庫(kù),這里就用到j(luò)son傳入,先看一下后臺(tái)如何生成要傳輸?shù)臄?shù)據(jù),感興趣的朋友可以參考下,希望可以幫助到你2013-04-04
JS實(shí)現(xiàn)數(shù)組的增刪改查操作示例
這篇文章主要介紹了JS實(shí)現(xiàn)數(shù)組的增刪改查操作,結(jié)合實(shí)例形式分析了javascript針對(duì)數(shù)組的追加、獲取、刪除、添加、修改等常見(jiàn)操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-08-08

