在簡析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中會致使錯誤。