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);