1. 程式人生 > >簡析JavaScript中的Function型別(二)——函式宣告與函式表示式的區別

簡析JavaScript中的Function型別(二)——函式宣告與函式表示式的區別

開發十年,就只剩下這套架構體系了! >>>   

簡析JavaScript中的Function型別(一)——函式名是指標中我們提到函式有三種定義方式:函式宣告、函式表示式、使用Function建構函式。其中,函式宣告和函式表示式是比較常用的方式,本篇文章就來講一下二者的區別。

先來看下面這段程式碼:

console.log(sum(1, 2));// 3
function sum(num1, num2){
  return num1 + num2;
}

先列印呼叫sum的結果,然後聲明瞭sum,按照通常的程式設計思路來看,這種寫法有點奇怪,我們知道在程式設計中有三種基本結構:順序結構、選擇結構、迴圈結構。所謂順序結構就是程式碼按照書寫的順序從上到下依次執行;選擇結構就是if判斷等,根據不同的情況執行不同的程式碼;迴圈結構如for迴圈等,在一定條件下反覆地執行某段程式碼。

上面的這段程式碼明顯是順序結構,從上到下依次執行,按理說執行第一行就應該報錯:諸如sum未定義之類。然而為什麼還能正確地列印結果呢?

現在我們將上面的例子改為函式表示式的語法來看下:

console.log(sum(1, 2));//Uncaught TypeError: sum is not a function
var sum = function(num1, num2){
  return num1 + num2;
};

發現報錯了,提示sum不是一個函式,正是我們期望的結果,那為什麼函式宣告會違背順序結構呢?

原來,JavaScript引擎在向執行環境中載入資料時,對函式宣告和函式表示式並非一視同仁。它會率先讀取函式宣告,並使其在執行任何程式碼之前可用;至於函式表示式,則必須等到引擎執行到它所在的程式碼行,才會真正被解釋執行。

在執行程式碼之前,JavaScript引擎讀取並將函式宣告新增到執行環境中,使之變為可讓其他程式碼訪問的狀態,這個過程稱為函式宣告提升。對於函式表示式,沒有函式宣告提升。上例中,在執行到函式所在行的語句之前,變數sum中不會儲存有對函式的引用,於是報錯;而且,由於第一行程式碼就報錯,所以實際上也不會執行到下一行。

因此,執行這兩段程式碼就出現了我們看到的樣子。

除了什麼時候可以通過變數訪問函式這一點區別之外,函式宣告與函式表示式的語法其實是等價的。

另外也可以同時使用函式宣告和函式表示式:

console(sum(1, 2));//Uncaught TypeError: sum is not a function
var sum = function sum(num1, num2) {
  return num1 + num2;
};

這等同於函式表示式,也不會進行函式宣告提升。不過,這種寫法在Safari