函數聲明式和函數表達式的區別


javascript中聲明函數常用的方法有兩種:函數聲明式和函數表達式.

一、定義

下面分別用兩種方法定義函數:

//函數聲明式
function greeting(){
      console.log("hello world");  
}

//函數表達式
var greeting = function(){
    console.log("hello world"); 
}

二、區別:

    1).以函數聲明的方法定義的函數,函數名是必須的,而函數表達式的函數名是可選的。

如果函數表達式聲明的函數有函數名,那么這個函數名就相當於這個函數的一個局部變量,只能在函數內部調用,舉個栗子:

var f = function fact(x) { 
    if (x <= 1) 
         return 1;
     else 
         return x*fact(x-1);
     };
 alert(fact());   // Uncaught ReferenceError: fact is not defined

    

    2).以函數聲明的方法定義的函數,函數可以在函數聲明之前調用,而函數表達式的函數只能在聲明之后調用(函數聲明整體會被提升到當前作用域的頂部,函數表達式也提升到頂部但是只有其變量名提升,變量提升詳解:https://www.cnblogs.com/vickylinj/p/12190847.html)  :

函數表達式與其他表達式一樣,在使用前必須先賦值。以下代碼會導致錯誤。

sayHi(); //錯誤:函數還不存在
var sayHi = function(){
alert("Hi!");
};

 

    3).以函數聲明的方法定義的函數並不是真正的聲明,它們僅僅可以出現在全局中,或者嵌套在其他的函數中,但是它們不能出現在循環,條件或者try/catch/finally中,而函數表達式可以在任何地方聲明。換句話說,函數聲明不是一個完整的語句,所以不能出現在if-else,for循環,finally,try catch語句以及with語句中。

為什么if else 語句里不能用函數聲明定義函數,而可以用函數表達式定義函數:

//不要這樣做!
if(condition){
function sayHi(){
alert("Hi!");
}
} else {
function sayHi(){
alert("Yo!");
}
}

表面上看,以上代碼表示在 condition 為 true 時,使用一個 sayHi()的定義;否則,就使用另一個定義。實際上,這在 ECMAScript 中屬於無效語法, JavaScript 引擎會嘗試修正錯誤,將其轉換為合理的狀態。但問題是瀏覽器嘗試修正錯誤的做法並不一致。大多數瀏覽器會返回第二個聲明,忽略condition; Firefox 會在 condition 為 true 時返回第一個聲明。因此這種使用方式很危險,不應該
出現在你的代碼中。不過,如果是使用函數表達式,那就沒有什么問題了。

為什么屬於無效的語法呢?這要從詞法作用來說,在《JavaScript語言精髓與編程實踐》第3章3.2基本語法的結構化含義 ,其中3.2.2.2語法作用域的相關性這一小節回答了以上的疑問,以下屬於摘抄部分:

 

上面的代碼function的語法作用比表達式的語法作用域高,所以上面if。。。else。。。語句不能包含函數的詞法作用域,JavaScript會將其理解為“平行”的關系,即如下所示:

本例中的代碼也會理解為:

if(condition){}

else {}


function sayHi(){
alert("Hi!");
}

function sayHi(){
alert("Yo!");

)

相當於第二個sayHi()函數覆蓋了第一個,所以會大多數瀏覽器會返回第二個聲明,忽略condition。

當然書中也建議如下作:

//可以這樣做
var sayHi;
if(condition){
sayHi = function(){
alert("Hi!");
};
} else {
sayHi = function(){
alert("Yo!");
};
}

這個例子不會有什么意外,不同的函數會根據 condition 被賦值給 sayHi

參照1:https://www.cnblogs.com/menghome/p/9277855.html

參照2:https://blog.csdn.net/qq_41846861/article/details/92692268


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM