
箭頭函式
E86之後,出現一種新的創造函式的方法,普遍被稱為箭頭函式,使得創造函式變得簡潔許多。相對於以前使用function關鍵字來宣告的用法,箭頭函式只需要用=>搭配括號跟區塊,就可以簡單地創造出函式,而因為這個等於大於的符號看起來很像箭頭,所以才被稱為箭頭函式。
const arrowFunction =() =>{
//do something.
};
箭頭函式的用法如上,可以看到這個用法已經不需要function關鍵字了,取而代之的是在括號跟區塊中間的箭頭。而你應該也可以注意到,箭頭函式的用法就與前面提到的函式表達式非常相近。沒錯,箭頭函式本身是匿名的,這意味它只可以被使用在函式表達式裡。
善用函式表達式
我們不妨試試看直接創造一個箭頭函式,但不將它指派給任何變數試試看。
()=>{
console.log("this is an arrow function");
};
你會發現,因為它是表達式,所以直接執行並不會出錯,就像我們直接在全域環境創造一個數字、一個字串或一個物件一樣。它會回傳一個函式物件,不過JavaScript看到這裡只會知道,「喔,這裡有一個函式」,所以該函式不會被執行,這段程式碼對JavaScript來講其實沒有什麼意義。
接下來,直覺敏銳的讀者應該可以猜到我想要說什麼了,其實轉個彎想一下,既然它只能用在表達式,那麼也許我也能把它用在前面立即執行函式(IIFE)的寫法上。
(()=>{
console.log("arrow function has been invoked");
})() //加上()會先去執行()的函式
一樣用括號,並把函式放進括號裡面,清楚告訴JavaScript這是一個表達式,而且我要優先運算,然後得到運算結果所回傳的函式物件之後,直接執行它。這樣一來,我就可以用簡潔的方法來撰寫IIFE了。
簡潔的回傳值
使用箭頭函式時,若所要回傳的內容單純只有一個表達式的時候,這個時候我們可以省略區塊{},而直接接在箭頭符號後面,這麼一來在函式被呼叫之後,這個表達式會直接被回傳。

當然,箭頭既然函式本身也是表達式,而JavaScript裡面函式又可以被傳給另為一個函式,那麼我應該有可以這麼做:

有看到特別的地方嗎?上方呼叫add函式的時候連續使用的兩個括號,這可不是連續呼叫兩次的意思!而是因為add函式本身回傳的是另外一個函式,會有兩次的呼叫是說:在執行第一個函式完收到第二個函式之後就直接執行了。
與function關鍵字的差異
箭頭函式相較於一般函式function關鍵字的用法,一般來說的優點都是語法簡潔、好閱讀等等,實際上也真的是這樣,它的確能夠讓開發者增加不少開發速度,不過它與使用function關鍵字創造出來的函式有些微的不同,甚至在某些點上有非常大的不一樣。這些差別不一定就是好或是壞,端看你如何使用而已,所以在這個段落的後面篇幅將會列舉一些較為明顯的差異來說明。
>>箭頭函式沒有arguments物件
什麼是arguments物件?arguments這個字代表了引數,另外一個與隻非常相近的詞稱為參數,引數用在函式宣告時,而呼叫函式時所傳進去的值則叫做參數。
換句話說,宣告一個函式時要先定義好參數,使函式時必須傳入引數。這兩個詞蠻常被搞混的,在別的地方搞錯沒有關係,不過在這邊為了介紹arguments物件,必須要釐清他們的差異才行。
function add(a,b){ //a,b是參數parameters
return a+b;
}
add(1,3); //引數
所以函式裡面的arguments物件其實就是用來接收傳入函式的引數。一個使用function關鍵字來創造的函式,在函式被呼叫時,除了直接透過函式的參數名稱來拿到對應傳入的引數值,但是也可以用物件來取用個別的引數內容,這是JavaScript提供的預設物件。
arguments物件是一個很像陣列的資料,你可以透過索引來拿到個別的引數值。

但它沒有陣列上那些方便的方法像是foreach或是map,真的單純只是長得像陣列而已,有些人會把它稱為是一個「類陣列」Array-Liked的資料結構。而一個跟陣列比較像的屬性只有length,所以如果要依序拿到每個引數值,則必須用一般的for迴圈。
function add(a, b) {
for (var i=0; i<arguments.length; i++){
if (typeof arguments[i] !== "number"){
return false;
}
}
return a+b;
}
add(1,2); //3
add(1,"some thing else"); //false
而arguments物件在箭頭函式內可不存在的,所以如果想要利用它來組合一些邏輯的話,千萬記得這一點。
const arrowFunction =() =>{
console.log(arguments);
}
arrowFunction();
//ReferenceError:arguments is not defined