標籤:
前言
動人js一段時間,我認為事情僅僅是一個很膚淺的理解。是非常欠缺的。所以開始使用部落格來對這一部分的知識做個慢慢的記錄和積累。
相信積少成多,慢慢的將這一部分的知識攻克!
第一篇記錄的不是相關的應用。而是非常底層的知識---JavaScript解析引擎。
想要瞭解這一部分的知識也是通過在項目中遇到的問題而聯想到的。
問題的背景
在一段指令碼中,啟動並執行順序是先將js檔案裡的alert()運行了一遍,然後當我詳細調用到那個函數的時候再運行這個函數。當時看到就產生了一個疑問:運行函數之前為什麼運行了alert(),非常明顯他沒有運行我定義的函數,卻運行了alert();
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>js運行測試</title></head><script>var a ;a = 1;function f1(){ alert("第一個函數"); }alert("測試");function f2(){ alert("第二個函數"); }alert(a);function f3(){ alert("第三個函數"); }</script><body><div><a herf="#" onclick="f1()">測試</a></div></body></html>
運行結果是:測試 1
須要瞭解的前提
須要瞭解兩個概念,一個是JavaScript解析引擎。另外一個是JavaScript解析引擎和瀏覽器的關係
1.JavaScript解析引擎 解釋運行指令碼的程式。
能夠看成是一個解譯器。
這個引擎須要完畢兩個功能:
一是解釋指令碼程式,將js代碼讀懂。
二是運行指令碼程式,將指令碼程式讀懂之後就要運行這個程式。
比方在一篇部落格中看到的一個範例。當你寫了 var a = 1 + 1; 這樣一段代碼,JavaScript引擎做的事情就是看懂(解析)你這段代碼,而且將a的值變為2。
看這個概念的時候還想起另外一個概念就是編譯器,它僅僅是將源碼編譯成第二種代碼(比方機器碼。或者位元組碼)。就好象是一個翻譯官,將中文翻譯成英文。它不可以運行這段程式。
2.JavaScript解析引擎和瀏覽器的關係 JavaScript解析引擎是瀏覽器的組成部分之中的一個。
當瞭解了前提之後我們知道,我們寫的js代碼是須要通過瀏覽器中的JavaScript解析引擎解析啟動並執行,詳細的解析機制大家能夠google一下,我對這部分瞭解不深,僅僅知道瞭解各大概。但是我認為這些知識對於我瞭解其它的知識已經足夠了。
解析機制分為兩個大過程,一個編譯過程,另外一個是運行過程。編譯過程終於是在記憶體中構建一個文法樹。運行過程就是依照文法樹來運行代碼。對於編譯和運行內部詳細的運行我就不清楚了。
js代碼在頁面中的運行順序 上面講到的都是一些理論知識。以下就來看看我們在實際應用過程中會js代碼在頁面中的運行順序。這些就是上面理論知識的一些非常形象的反應。
1. 引擎對js解析---先行編譯和運行循序關聯性 它會在先行編譯期對全部聲明的變數和函數進行處理。所以,就會出現當JavaScript解譯器運行以下指令碼時不會報錯:
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>js運行測試</title></head><script>alert(a); //undefinedvar a ;a = 1;function f1(){ alert("第一個函數"); }alert("測試"); //測試function f2(){ alert("第二個函數"); }alert(a); //1function f3(){ alert("第三個函數"); }</script><body><div><a herf="#" onclick="f1()">測試</a></div></body></html>運行結果是: undefined 測試 1
先行編譯做的工作:將聲明的變數和函數做處理。從而使其在運行期間對全部的代碼都是可見的。
可是,你也會看到。運行上面代碼。提示的值是 undefined,而不是1。
這是由於,變數初始化過程發生在運行期,而不是先行編譯期。
在運行期,JavaScript解譯器是按著代碼先後順序進行解 析的,假設在前面程式碼中沒有為變數賦值。則JavaScript解譯器會使用預設值undefined。由於在第二行中為變數a賦值了。所以在第三行代 碼中會提示變數a的值為1,而不是undefined。
2. 檔案流載入時---js依照HTML文檔流順序運行
js能夠看成HTML文檔的組成部分。
HTML文檔是從上到下逐步解析的。不管是使用<script></script>塊還是使用外部參考的js檔案都是如此。
使用外部js檔案引用,將上面的代碼寫到js檔案裡。運行結果不變
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>js運行測試</title></head><script type="text/javascript" src="Untitled-2.js"></script><body><div><a herf="#" onclick="f1()">測試</a></div></body></html>
js檔案
var a ;a = 1;function f1(){ alert("第一個函數"); }alert("測試");function f2(){ alert("第二個函數"); }alert(a);function f3(){ alert("第三個函數"); }
運行結果:測試 1 3. 檔案流載入完畢之後---依照事件機制改變js運行順序
類似於調用函數,在哪裡調用到就在此處運行,假設沒有調用到就不運行。從上面的代碼中能夠看到。為a標籤加入了點擊事件。所以當單擊的時候會運行相應的函數
總結
所以能夠解釋為什麼alert()運行了,而函數沒有運行。js解析引擎要有一個先行編譯過程,對定義的變數和函數做處理。
同一時候js還要依據HTML文檔流的順序運行。
這就是運行我自訂的函數之前的過程,而我所以的運行自訂的函數事實上是事件機制調用js的一個體現。
著作權聲明:本文部落格原創文章。部落格,未經同意,不得轉載。
JavaScript運行命令