函數(shù)表達式和函數(shù)聲明的區(qū)別。

大家好,我是IT修真院萌新分院的王寒,一枚正直,純潔,善良的前端程序員。

今天給大家分享一下函數(shù)表達式和函數(shù)聲明有什么區(qū)別?

1.背景介紹

函數(shù)就是一段可以反復(fù)調(diào)用的代碼塊。函數(shù)聲明由三部分組成:函數(shù)名,函數(shù)參數(shù),函數(shù)體。 整體的構(gòu)造是function命令后面是函數(shù)名,函數(shù)名后面是一對圓括號,里面是傳入函數(shù)的參數(shù)。 函數(shù)體放在大括號里面。當(dāng)函數(shù)體沒有使用return關(guān)鍵字返回函數(shù)時,函數(shù)調(diào)用時返回默認的undefined; 如果有使用return語句,則返回指定內(nèi)容。函數(shù)最后不用加上冒號。

function keith() {}

? ? ? ? ? ? ? ? ? ? ? ? ? ?? console.log(keith())?? // 'undefined'

? ? ? ? ? ? ? ? ? ? ? ? ? ?? function rascal(){

? ? ? ? ? ? ? ? ? ? ? ? ? ?? return 'rascal';

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? console.log(rascal())? ? // 'rascal'

2.知識剖析

什么是FUNCTION DECLARATION(函數(shù)聲明)? Function Declaration 可以定義命名的函數(shù)變量,而無需給變量賦值。Function Declaration 是一種獨立的結(jié)構(gòu),不能嵌套在非功能模塊中。 就是使用function關(guān)鍵字聲明一個函數(shù),再指定一個函數(shù)名,叫函數(shù)聲明

函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,也就是說函數(shù)聲明是在瀏覽器準備解析并執(zhí)行腳本代碼的時候執(zhí)行的。所以,當(dāng)去調(diào)用一個函數(shù)聲明時,可以在其前面調(diào)用并且不會報錯。

console.log(rascal())?? // 'rascal'

? ? ? ? ? ? ? ? ? ? ? ? ? ? function rascal(){

? ? ? ?? return 'rascal';

? ?? }

什么是FUNCTION EXPRESSION(函數(shù)表達式)? Function Expression 將函數(shù)定義為表達式語句(通常是變量賦值)的一部分。通過 Function Expression 定義的函數(shù)可以是命名的,也可以是匿名的。Function Expression 不能以“function”開頭。 使用function關(guān)鍵字聲明一個函數(shù),但未給函數(shù)命名,最后將匿名函數(shù)賦予一個變量,叫函數(shù)表達式

簡單點來說函數(shù)表達式是把一個匿名函數(shù)賦給一個全局變量。這個匿名函數(shù)又稱為函數(shù)表達式,因為賦值語句的等號右側(cè)只能放表達式。函數(shù)表達式末尾需要加上分號,表示語句結(jié)束。

var keith = function() {

? ? ? ? //函數(shù)體

? ? };

函數(shù)表達式存儲在變量后,變量也可作為一個函數(shù)使用:

var x = function (a, b) {return a * b};

? ? ? ? ? ? ? ? ? ? ? ? ? ? alert= x(4, 3);

以上函數(shù)實際上是一個 匿名函數(shù) (函數(shù)沒有名稱)。 函數(shù)存儲在變量中,不需要函數(shù)名稱,通常通過變量名來調(diào)用。

var x = function (a, b) {return a * b};

? ? ? ? ? ? ? ? ? ? ? ? var z = x(4, 3);

? ? ? ? ? ? ? ? ? ? ? ? alert= z;

3.常見問題

一、什么是JavaScript函數(shù)?

二、兩者具體有哪些區(qū)別呢?

4.解決方案

1.JavaScript函數(shù)

函數(shù)是由事件驅(qū)動的或者當(dāng)它被調(diào)用時執(zhí)行的可重復(fù)使用的代碼塊

函數(shù)語法:函數(shù)就是包裹在花括號中的代碼塊,使用了關(guān)鍵詞function:

function functionname(){

執(zhí)行代碼

}

當(dāng)調(diào)用該函數(shù)時,會執(zhí)行函數(shù)內(nèi)的代碼。

可以在某事件發(fā)生時直接調(diào)用函數(shù)

調(diào)用帶參數(shù)的函數(shù),在調(diào)用函數(shù)時,可以向其傳遞值,這些值被稱為參數(shù)。這些參數(shù)可以在函數(shù)中使用。 可以發(fā)送任意多的參數(shù),由逗號(,)分隔:

myFunction(argument1,argument2)

當(dāng)聲明函數(shù)時,把參數(shù)作為變量來聲明:

function myFunction(var1,var2){

代碼

}

點擊這個按鈕,來調(diào)用帶參數(shù)的函數(shù)

functionmyFunction(name,job){

alert("Welcome "+ name +", the "+ job);

}

2.函數(shù)聲明和函數(shù)表達式的區(qū)別

1.函數(shù)聲明中函數(shù)名是必須的;函數(shù)表達式中則是可選的

//函數(shù)聲明

function sum(a, b) {

return a + b;

}

alert(sum(1, 2));

//函數(shù)表達式

var s = function sum(a, b) {

return a + b;

}

alert(s(1, 2));

var s = function(a, b) {

return a + b;

}

alert(s(1, 2));//以上兩種都可以

2.用函數(shù)聲明定義的函數(shù),函數(shù)可以在函數(shù)聲明之前調(diào)用,而用函數(shù)表達式定義的函數(shù)只能在聲明之后調(diào)用。

//函數(shù)聲明

alert(sum(1, 2));//3

function sum(a, b) {

return a + b;

}

//函數(shù)表達式:發(fā)生錯誤

try {

alert(s(1, 2));

var s = function sum(a, b) {

return a + b;

}

}

catch (e) {

alert("wrong!");

}

3.以函數(shù)聲明的方法定義的函數(shù)并不是真正的聲明,它們僅僅可以出現(xiàn)在全局中,或者嵌套在其他的函數(shù)中, 但是它們不能出現(xiàn)在循環(huán),條件或者try/catch/finally中,而 函數(shù)表達式可以在任何地方聲明.

//函數(shù)聲明式

function greeting(){

?? console.log("hello world");

}

//函數(shù)表達式

var greeting = function(){

? console.log("hello world");

}

5.擴展思考

使用function關(guān)鍵字聲明一個函數(shù),再指定一個函數(shù)名,叫函數(shù)聲明。

function fn(){……}

使用function關(guān)鍵字聲明一個函數(shù),但未給函數(shù)命名,最后將匿名函數(shù)賦予一個變量,叫函數(shù)表達式。

var fn=function(){……}

使用function關(guān)鍵字聲明一個函數(shù),但未給函數(shù)命名,這個又稱之為什么呢?是屬于以上兩種類型的哪一種?

function(){……}

6.參考文獻

函數(shù)聲明與函數(shù)表達式以及立即執(zhí)行函數(shù)的討論

7.更多討論

問題一:關(guān)于立即執(zhí)行函數(shù)的討論

回答:也就是說只有函數(shù)表達式才能實現(xiàn)立即執(zhí)行,匿名函數(shù)也是函數(shù)表達式為何不能立即執(zhí)行呢?

因為匿名函數(shù)開始的function會被JavaScript引擎識別為函數(shù)聲明的開始,所以加上括號也不會被執(zhí)行

而加上(),!,+,-等符號為什么就可以了呢?

因為加上這些符號就可以告訴js引擎這不是函數(shù)聲明了。

問題二:給匿名函數(shù)用小括號包起來,為什么能執(zhí)行?

//匿名函數(shù):

function(){?  //如果不加小括號則會報錯!

alert('彈出框');

}();

//添加小括號后的匿名函數(shù)

(function(){

alert('彈出框');

})();

回答:小括號能把我們的表達式組合分塊,并且每一塊,也就是每一對小括號, 都有一個返回值。這個返回值實際上也就是小括號中表達式的返回值。 加上括號也不會被執(zhí)行

問題三:什么是自執(zhí)行函數(shù)?

回答:在JavaScript里,任何function在執(zhí)行的時候都會創(chuàng)建一個執(zhí)行上下文, 因為function聲明的變量和function有可能只在該function內(nèi)部,這個上下文, 在調(diào)用function的時候,提供了一種簡單的方式來創(chuàng)建自由變量或私有子function。

函數(shù)表達式的作用域

如果函數(shù)表達式聲明的函數(shù)有函數(shù)名,那么這個函數(shù)名就相當(dāng)于這個函數(shù)的一個局部變量,只能在函數(shù)內(nèi)部調(diào)用

var f = function fact(x) {

? ? ? ? if (x <= 1)

? ? ? ? ? ? ? ? return 1;

? ? ? ? else

? ? ? ? ? ? ? ? return x*fact(x-1);

? ? ? ? ? ? };

? ? ? ? ? ? ? alert(fact());? // Uncaught ReferenceError: fact is not defined

fact()在函數(shù)內(nèi)部可以調(diào)用,在函數(shù)外部調(diào)用就會報錯:fact未定義

問題:

1.變量提升:

答案:請點擊

2.?函數(shù)聲明可以先調(diào)用再聲明,是因為變量提升嗎?

這個問題在上面的第一個問題里有提到:

函數(shù)及變量的聲明都將被提升到函數(shù)的最頂部,所以函數(shù)聲明會被先調(diào)用再聲明是以為變量提升

3.函數(shù)聲明在條件語句中使用時注意的問題?

在不同的環(huán)境下用函數(shù)聲明會得到不同的效果

這也是函數(shù)聲明的另外一個重要的特點,即通過條件語句控制函數(shù)聲明的行為并未標準化,因此不同環(huán)境下可能會得到不同的結(jié)果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容