js 程序執行與順序實現詳解

1.函數的聲明和調用 
        JavaScript是一種描述型腳本語言,由瀏覽器進行動態的解析與執行。函數的定義方式大致有如下兩種,瀏覽器對於不一樣的方式有不一樣的解析順序。 
代碼以下: javascript

//「定義式」函數定義 
function Fn1(){ 
  alert("Hello World!"); 
} 
//「賦值式」函數定義 
var Fn2 = function(){ 
  alert("Hello wild!"); 
} 

 2.  函數的編譯html

        頁面加載過程當中,瀏覽器會對頁面上或載入的每一個js代碼塊(或文件)進行掃描,若是遇到定義式函數,則進行預處理(相似於C等的編譯),處理完成以後再開始由上至下執行;遇到賦值式函數,則只是將函數賦給一個變量,不進行預處理(相似1中變量必須先定義後引用的原則),待調用到的時候才進行處理。下面舉個簡單的例子: 
代碼以下: java

//「定義式」函數定義 
Fn1(); 
function Fn1(){ 
  alert("Hello World!"); 
} 

正常執行,彈出「Hello World!」,瀏覽器對Fn1進行了預處理,再從Fn1();開始執行。 瀏覽器


代碼以下: 多線程

//「賦值式」函數定義 
Fn2(); 
var Fn2 = function(){ 
    alert("Hello wild!"); 
} 


Firebug報錯:Fn2 is not a function,瀏覽器未對Fn2進行預處理,依序執行,因此報錯Fn2未定義。 

3. 代碼塊及js文件的處理 
    「代碼塊」是指一對<script type=」text/網頁特效」></script>標籤包裹着的js代碼,文件就是指文件啦。瀏覽器對每一個塊或文件進行獨立的掃描,而後對全局的代碼進行順序執行(2中講到了)。因此,在一個塊(文件)中,函數能夠在調用以後進行「定義式」定義;但在兩個塊中,定義函數所在的塊必須在函數被調用的塊以前。 很繞口,看例子好了: 
代碼以下: 異步

<script type="text/javascript"> 
     Fn(); 
</script> 
<script type="text/javascript"> 
function Fn(){ 
     alert("Hello World!"); 
} 
</script> 


// 報錯:Fn is notdefined,兩個塊換過來就對了 ide


4. 重複定義函數會覆蓋前面的定義 
這和變量的重複定義是同樣的,代碼: 
代碼以下: 函數

function fn(){ 
    alert(1); 
} 
function fn(){ 
    alert(2); 
} 
fn(); 

// 彈出:「2」 測試


若是是這樣呢: 
代碼以下: 操作系統

fn(); 
function fn(){ 
  alert(1); 
} 
function fn(){ 
  alert(2); 
} 

// 仍是彈出:「2」 
5. body的onload函數與body內部函數的執行 
body內部的函數會先於onload的函數執行,測試代碼: 
代碼以下: 

//html head... 
<script type="text/javascript"> 
function fnOnLoad(){ 
  alert("I am outside the Wall!"); 
} 
</script> 
<body onload="fnOnLoad();"> 
<script type="text/javascript"> 
  alert("I am inside the Wall.."); 
</script> 
</body> 


//先彈出「I am inside the Wall..」; 
//後彈出「I am outside the Wall!」 

body的onload事件觸發條件是body內容加載完成,而body中的js代碼會在這一事件觸發以前運行(爲何呢?6告訴你..) 

6. JavaScript是多線程or單線程? 
嚴格來講,JavaScript是沒有多線程概念的,全部的程序都是「單線程」依次執行的。 
代碼以下: 

function fn1(){ 
var sum = 0; 
for(var ind=0; ind<1000; ind++) { 
sum += ind; 
} 
alert("答案是"+sum); 
} 
function fn2(){ 
alert("早知道了,我就是不說"); 
} 
fn1(); 
fn2(); 


//先彈出:「答案是499500」, 
//後彈出:「早知道了,我就是不說」 

那你確定要問:那延時執行、Ajax異步加載,不是多線程的嗎?沒錯,下面這樣的程序確實看起來像「多線程」: 
代碼以下: 

function fn1(){ 
setTimeout(function(){ 
alert("我先調用") 
},1000); 
} 
function fn2(){ 
alert("我後調用"); 
} 
fn1(); 
fn2(); 


// 先彈出:「我後調用」, 
// 1秒後彈出:「我先調用」 


        看上去,fn2()和延時程序是分兩個過程再走,但其實,這是JavaScript中的「回調」機制在起做用,相似於操做系統中的「中斷和響應」 —— 延時程序設置一個「中斷」,而後執行fn2(),待1000毫秒時間到後,再回調執行fn1()。 
        一樣,5中body的onload事件調用的函數,也是利用了回調機制——body加載完成以後,回調執行fnOnLoad()函數。 
        Ajax請求中的數據處理函數也是同樣的道理。 
 
7. 回調函數 
    如6所說,最多見的回調就是onclick、onmouseo教程ver、onmousedown、onload等等瀏覽器事件的調用函數;還有Ajax異步請求數據的處理函數;setTimeOut延時執行、setInterval循環執行的函數等。 
代碼以下: 

function onBack(num){ 
alert("姍姍我來遲了"); 
// 執行num個耳光 
} 
function dating(hours, callBack){ 
var SP= 0; // SP,憤怒值 
//女豬腳在雪裏站了hours個鐘頭 
//循環開始.. 
SP ++; 
//循環結束... 
callBack(SP); 
} 
dating(1, onBack); 
相關文章
相關標籤/搜索