簡析JavaScript中的Function類型(二)——函數聲明與函數表達式的區別

簡析JavaScript中的Function類型(一)——函數名是指針中咱們提到函數有三種定義方式:函數聲明、函數表達式、使用Function構造函數。其中,函數聲明和函數表達式是比較經常使用的方式,本篇文章就來說一下兩者的區別。javascript

先來看下面這段代碼:java

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

先打印調用sum的結果,而後聲明瞭sum,按照一般的編程思路來看,這種寫法有點奇怪,咱們知道在編程中有三種基本結構:順序結構、選擇結構、循環結構。所謂順序結構就是代碼按照書寫的順序從上到下依次執行;選擇結構就是if判斷等,根據不一樣的狀況執行不一樣的代碼;循環結構如for循環等,在必定條件下反覆地執行某段代碼。編程

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

如今咱們將上面的例子改成函數表達式的語法來看下:.net

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

發現報錯了,提示sum不是一個函數,正是咱們指望的結果,那爲何函數聲明會違背順序結構呢?指針

原來,JavaScript引擎在向執行環境中加載數據時,對函數聲明和函數表達式並不是一視同仁。它會率先讀取函數聲明,並使其在執行任何代碼以前可用;至於函數表達式,則必須等到引擎執行到它所在的代碼行,纔會真正被解釋執行。code

在執行代碼以前,JavaScript引擎讀取並將函數聲明添加到執行環境中,使之變爲可以讓其餘代碼訪問的狀態,這個過程稱爲函數聲明提高。對於函數表達式,沒有函數聲明提高。上例中,在執行到函數所在行的語句以前,變量sum中不會保存有對函數的引用,因而報錯;並且,因爲第一行代碼就報錯,因此實際上也不會執行到下一行。blog

所以,運行這兩段代碼就出現了咱們看到的樣子。ip

除了何時能夠經過變量訪問函數這一點區別以外,函數聲明與函數表達式的語法實際上是等價的。get

另外也能夠同時使用函數聲明和函數表達式:

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

這等同於函數表達式,也不會進行函數聲明提高。不過,這種寫法在Safari中會致使錯誤。

相關文章
相關標籤/搜索