目錄
腳本處理模型
javascript的基本特點
腳本處理模型
源碼處理
函數解析
代碼執行
擴展:javascript程序與宿主環境進行交互,是通過一系列預定義的方法和屬性實現的,這些方法和屬性會再映射成浏覽器的內部原生代碼,所以與其他很對常規的編程語言不同,浏覽器開放的這些借口往往受限且有針對性。
首先,無論是獨立的窗口還是在框架裡面,每個展示在浏覽器裡面的html文檔,都被賦予了一個獨立的javascript執行環境實例,在這個環境裡面加載的腳本的所有全局變量和函數都擁有一個獨立的命名空間。
然後,同一個文檔的所有腳本都運行在同一個執行環境裡面,共享同一個沙箱,並且能夠通過浏覽器提供的API與其他上下文環境交互。
最後:在特定的執行上下文裡面,每段javascript代碼塊都是自成體系處理的,順序也基本確定。每段代碼塊都是由若干符合語法格式的獨立單元組成,處理的過程包括清晰而且連續的三個步驟:源碼處理,函數解析,代碼執行。
源碼處理階段會檢查腳本代碼塊裡面的語法,通常會先把代碼轉換成中間層的二進制映像,這樣才能或得到令人滿意的執行速度。在徹底完成這一步驟之前,這些二進制代碼對全局並無影響。如果源碼處理階段出錯,整個有問題的代碼塊都會被棄用;然後解析器會繼續處理下一段代碼塊。
完成了上一步驟之後,接下來就是解析器對當前代碼塊裡所有具名的全局函數進行識別並注冊。在這一階段完成之後,這些函數才能被執行代碼所調用。
對於代碼
<script>
hello_world();
function hello_world(){
console.log('hello, man');
}
</script>
因為javascript在執行前會額外預處理,因此上面的寫法會成功執行。
而對於代碼
<script>
hello_world();
</script>
<script>
function hello_world(){
console.log('hello, man');
}
</script>
對於這段代碼會因為運行的時候錯誤而執行失敗,因為代碼裡每段獨立的代碼塊並不是同時處理的,這是根據javascript引擎讀取代碼塊的先後順序決定的。在執行第一個代碼塊的時候,定義hello_world()的那塊代碼塊還沒有被解析呢。
再看代碼
<script>
hello_world();
var hello_world = function(){
console.log('hello, men');
}
</script>
出現這個現象的原因是:在調用hello_world()的時候,對於hello_world變量的賦值還沒有開始呢!
解釋:javascript這種全局名稱解析模型只針對於函數有效,而對於變量的聲明卻並非如此。與其他腳本語言類似,變量是按照執行的時候出現的順序注冊的。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-11/93143p2.htm