在 js 中函數(shù)被認(rèn)為是第一等公民,而且對(duì)于創(chuàng)建函數(shù)來(lái)說(shuō)這個(gè)概念是非常重要的.
不像別的語(yǔ)言,在 js 中,我們有三種不同的創(chuàng)建函數(shù)的方式.
1.函數(shù)聲明
函數(shù)表達(dá)式
命名函數(shù)表達(dá)式
######函數(shù)聲明
function [name](param1, param2, ...param3) {
? ? // Function Body & Logic
}
在這個(gè)例子里,我們把function 關(guān)鍵字放在函數(shù)名字前面.
一個(gè)主要的好處是這個(gè)函數(shù)會(huì) 提升
因?yàn)檫@個(gè),我們可以先執(zhí)行這個(gè)函數(shù),再聲明它.
當(dāng)你想要將某些抽象的邏輯放到函數(shù)內(nèi)部,但是實(shí)際上實(shí)現(xiàn)是在以后完成.
最佳實(shí)踐: 定義好了函數(shù)之后立即執(zhí)行它,比依賴js 的提升要好
######函數(shù)表達(dá)式
任何給某個(gè)變量賦值的語(yǔ)句都可以叫做表達(dá)式
var a= 100;
var b= 'hello worl'
在某些情況下,會(huì)創(chuàng)建沒(méi)有名字的函數(shù)并賦值給某個(gè)變量
var [name] = function(param1, param2, ...param3) {
? ? // Function Body & Logic
}
foo(1,3,4);
**限制:**函數(shù)不能在被定義之前執(zhí)行
var num1 = 10;
var num2 = 20;
var result = add(num1, num2);?
//
Uncaught TypeError: add is not a functionvar add = function(param1, param2) {
? ? return param1 + param2 ;
}
下面的方式會(huì)執(zhí)行
var num1 = 10;
var num2 = 20;
var add = function(param1, param2) {
? ? return param1 + param2 ;
}
var result = add(num1, num2); // ==> 30
######命名函數(shù)表達(dá)式 - 包含兩種方法
現(xiàn)在你已經(jīng)知道函數(shù)表達(dá)式和函數(shù)聲明之間的區(qū)別了,現(xiàn)在我們看下兩者的混合吧
var num1 = 10;
var num2 = 20;
var addVariale = function addFunction(param1,param2) {
return param1+ param2
}
注意,上面的代碼已經(jīng)不是匿名的而是有一個(gè)addFunction 的名字,同時(shí),它賦值給了一個(gè)變量 - addVariale .
現(xiàn)在你雖然加了一個(gè)名字到function 關(guān)鍵字后面,但是這不意味著你可以直接執(zhí)行這個(gè)函數(shù)名.
var result = addFunction(num1, num2);
// ==> Uncaught ReferenceError: addFunction is not defined
相反,只有賦值變量 addVariable 可以引用和執(zhí)行
var result = **addVariable**(num1, num2);
// ==> 30
#####重點(diǎn)
1.addFunction掩蓋了調(diào)試工具調(diào)用堆棧中的addVariable。
1*CPUa1X3-O55XPPMz7MBVkA
命名函數(shù)表達(dá)式
1*QsAXJNRrrI49ZkDo3WCrnA
函數(shù)表達(dá)式
2.在命名函數(shù)表達(dá)式的情況下,調(diào)用外部拋出的addFunction()錯(cuò)誤
未捕獲錯(cuò)誤: addFunction 沒(méi)找到
但是你可以在函數(shù)內(nèi)部調(diào)用,這樣子會(huì)執(zhí)行
var num1 = 10;
var num2 = 20;
var addVariable = function addFunction(param1, param2) {
? var res = param1 + param2;
? if (res === 30) {
? ? ? ? res =
addFunction(res, 10);
? }
? return res;
}
var result = addVariable(num1, num2); // ==> 40
在這個(gè)場(chǎng)景上,查看 res 是 30 的話,調(diào)用同樣的函數(shù),并把賦值 30 和 10,作為參數(shù),最后會(huì)返回一個(gè) 40 作為輸出結(jié)果.
3.在IE8及以下版本中使用命名函數(shù)表達(dá)式的一個(gè)嚴(yán)重警告是,它錯(cuò)誤地在兩個(gè)完全不同的時(shí)間創(chuàng)建了兩個(gè)完全獨(dú)立的函數(shù)對(duì)象(Double take)。
如果你需要支持 IE8,最好使用函數(shù)表達(dá)式和函數(shù)聲明,避免使用命名函數(shù)表達(dá)式.
希望這個(gè)文章會(huì)給你一個(gè)的關(guān)于函數(shù)聲明,函數(shù)表達(dá)式,命名函數(shù)表達(dá)式的清晰的概念
希望你可以在下面留言寫(xiě)下你的想法,反饋和疑慮,我們可以更深的討論一下.
原文地址: https://medium.com/@raviroshan.talk/javascript-function-declaration-vs-expression-f5873b8c7b38