理解Javascript_12_执行模型浅析
大家有沒(méi)有想過(guò),一段javascript腳本從載入瀏覽器到顯示執(zhí)行都經(jīng)過(guò)了哪些流程,其執(zhí)行次序又是如何。本篇博文將引出'javascript執(zhí)行模型'的概念,并帶領(lǐng)大家理解javascript在執(zhí)行時(shí)的處理機(jī)制。
?
簡(jiǎn)單的開(kāi)始
簡(jiǎn)單的代碼:
<script type="text/javascript" src="xxx.js"></script> <script type="text/javascript">var i = 10;function say(msg){alert(msg);} </script> <script type="text/javascript">j=100;say("hello world"); </script>上面代碼段的運(yùn)行順序是:
step1. 讀入第一個(gè)代碼段 step2. 做語(yǔ)法分析,有錯(cuò)則報(bào)語(yǔ)法錯(cuò)誤(比如括號(hào)不匹配等),并跳轉(zhuǎn)到step5 step3. 創(chuàng)建全局執(zhí)行環(huán)境(對(duì)var變量和function定義做"預(yù)解析") step4. 執(zhí)行代碼段(調(diào)用函數(shù)、進(jìn)入eval時(shí),都會(huì)創(chuàng)建新的執(zhí)行環(huán)境),有錯(cuò)則報(bào)錯(cuò)(比如變量未定義) step5. 如果還有下一個(gè)代碼段,則讀入下一個(gè)代碼段,重復(fù)step2 step6. 結(jié)束對(duì)于step1中的'腳本段'指的是<script>... ...</script>標(biāo)簽中的內(nèi)容,還包括外部引入的腳本文件,如<script src="xxx.js"></script>也被列是腳本段的范疇。那step2中的語(yǔ)法分析又是什么呢?簡(jiǎn)單的理解語(yǔ)法分析就是查看Javascript代碼的語(yǔ)法結(jié)構(gòu)是否正確。如:
<script type="text/javascript"> var a = 10; if(a>10{alert('yes'); } </script>很明顯,代碼無(wú)法通過(guò)語(yǔ)法分析,if這個(gè)條件語(yǔ)句的輸寫(xiě)語(yǔ)法是錯(cuò)誤的。step3和step4中的'執(zhí)行環(huán)境'是指什么,全局執(zhí)行環(huán)境和調(diào)用函數(shù)創(chuàng)建的執(zhí)行環(huán)境有什么區(qū)別?執(zhí)行環(huán)境內(nèi)部又有哪些處理?... ...
?
注:下面的部分內(nèi)容為原來(lái)《javascript提速_01_引用變量?jī)?yōu)化》一文中的前兩節(jié)的完整版本。
?
關(guān)于執(zhí)行環(huán)境(Execution Context)
所有 JavaScript 代碼都是在一個(gè)執(zhí)行環(huán)境中被執(zhí)行的。它是一個(gè)概念,一種機(jī)制,用來(lái)完成JavaScript運(yùn)行時(shí)作用域、生存期等方面的處理。
?
可執(zhí)行的JavaScript代碼分三種類型:
1. Global Code,即全局的、不在任何函數(shù)里面的代碼,例如:一個(gè)js文件、嵌入在HTML頁(yè)面中的js代碼等。
2. Eval Code,即使用eval()函數(shù)動(dòng)態(tài)執(zhí)行的JS代碼。
3. Function Code,即用戶自定義函數(shù)中的函數(shù)體JS代碼。
不同類型的JavaScript代碼具有不同的Execution Context
?
在一個(gè)頁(yè)面中,第一次載入JS代碼時(shí)創(chuàng)建一個(gè)全局執(zhí)行環(huán)境,當(dāng)調(diào)用一個(gè) JavaScript 函數(shù)時(shí),該函數(shù)就會(huì)進(jìn)入相應(yīng)的執(zhí)行環(huán)境。如果又調(diào)用了另外一個(gè)函數(shù)(或者遞歸地調(diào)用同一個(gè)函數(shù)),則又會(huì)創(chuàng)建一個(gè)新的執(zhí)行環(huán)境,并且在函數(shù)調(diào)用期間執(zhí)行過(guò)程都處于該環(huán)境中。當(dāng)調(diào)用的函數(shù)返回后,執(zhí)行過(guò)程會(huì)返回原始執(zhí)行環(huán)境。因而,運(yùn)行中的 JavaScript 代碼就構(gòu)成了一個(gè)執(zhí)行環(huán)境棧。
?
讓我們來(lái)看一個(gè)示例:
<script type="text/javascript">function Fn1(){function Fn2(){alert(document.body.tagName);//BODY//other code...}Fn2();}Fn1();//code here </script>以上是程序從上到下執(zhí)行時(shí)的執(zhí)行環(huán)境棧情況圖。
?
補(bǔ)充說(shuō)明:
全局執(zhí)行環(huán)境對(duì)應(yīng)的是Global Code(全局代碼)
Fn1執(zhí)行環(huán)境、Fn2執(zhí)行環(huán)境通稱為函數(shù)執(zhí)行環(huán)境對(duì)應(yīng)的是Function Code(函數(shù)定義代碼)
?
程序在進(jìn)入每個(gè)執(zhí)行環(huán)境的時(shí)候都會(huì)創(chuàng)建一個(gè)叫做Variable Object的對(duì)象。
針對(duì)于函數(shù)執(zhí)行環(huán)境,函數(shù)對(duì)應(yīng)的每一個(gè)參數(shù)、局部變量、內(nèi)部方法都會(huì)在Variable Object上創(chuàng)建一個(gè)屬性,屬性名為變量名,屬性值為變量值。針對(duì)于全局執(zhí)行環(huán)境,具有相同的行為。但是要強(qiáng)調(diào)的一點(diǎn)是在全局執(zhí)行環(huán)境中Varible Object就是Global Object,關(guān)于Global Object在《理解Javascript_03_javascript全局觀》中已經(jīng)說(shuō)明了,可以簡(jiǎn)單的理解為window對(duì)象。這也就解釋了全局方法和全局變量為什么都是window對(duì)象的屬性或方法的原因,請(qǐng)看如下代碼:
var num = 123; alert(window.num);//123 function say(msg){alert(msg); } window.say("hello");//hello最后要說(shuō)的是,Variable Object對(duì)象是一個(gè)內(nèi)部對(duì)象,JS代碼中無(wú)法直接訪問(wèn)。
?
關(guān)于Scope/Scope Chain
?在訪問(wèn)變量時(shí),就必須存在一個(gè)可見(jiàn)性的問(wèn)題,這就是Scope。更深入的說(shuō),當(dāng)訪問(wèn)一個(gè)變量或調(diào)用一個(gè)函數(shù)時(shí),JavaScript引擎將不同執(zhí)行位置上的Variable Object按照規(guī)則構(gòu)建一個(gè)鏈表,在訪問(wèn)一個(gè)變量時(shí),先在鏈表的第一個(gè)Variable Object上查找,如果沒(méi)有找到則繼續(xù)在第二個(gè)Variable Object上查找,直到搜索結(jié)束。這也就形成了Scope Chain的概念。
?
作用域鏈圖,清楚的表達(dá)了執(zhí)行環(huán)境與作用域的關(guān)系(一一對(duì)應(yīng)的關(guān)系),作用域與作用域之間的關(guān)系(鏈表結(jié)構(gòu),由上至下的關(guān)系)。
?
注:本文僅僅從全局角度的看待javascript執(zhí)行模型,因此不夠深入,具體執(zhí)行細(xì)節(jié),請(qǐng)參見(jiàn)后續(xù)博文。
?
參考:
http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html http://lifesinger.org/blog/2009/01/javascript-run-mechanism/轉(zhuǎn)載于:https://www.cnblogs.com/fool/archive/2010/10/16/1853326.html
總結(jié)
以上是生活随笔為你收集整理的理解Javascript_12_执行模型浅析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jquery调用asp.net 页面后台
- 下一篇: Javascript中正则表达式的全局匹