Day26 | JS 箭頭函式
❒ 箭頭函式架構
- 可把
{}大括號省略。- 箭頭函式後的
{}是作為箭頭函式裡面的程式碼片段的範圍使用,並不是物件實字中使用的{}大括號。所以如果箭頭函式要回傳一個物件內容,須於{}外層加上()包覆 →({})。
- 箭頭函式後的
- 如果程式碼內容為表達式 ( 會回傳值 ),沒有其他內容就可以做縮寫「 省略
{}大括號 &return」。 - 如果只有一個參數,可省略
()括號,但如果沒有參數要保留()括號。 - 如果大括號內有多行程式,建議不要省略
{}大括號 &return。
1 | // 箭頭函式回傳裡面的物件 |
❒ 箭頭函式與傳統函式差異
- 箭頭函式沒有
argument這個參數。 - 箭頭函式沒有自己的
this,所以它的this會指向它的外層。 - 箭頭函式無法透過
call,apply,bind重新給予this。 - 箭頭函式不能當建構函式使用。
➊ 箭頭函式沒有 argument 這個參數
傳統函式在執行時會自動帶上 argument 這個參數,但箭頭函式沒有 argument 這個參數。
範例 1. 傳統函式
1 | const nums = function() { |

範例 2. 箭頭函式
1 | const nums = () => { |
會顯示錯誤訊息 Uncaught ReferenceError: arguments is not defined at nums
➤ 其餘參數:解決箭頭函式沒有 argument 的方式
有時候也會遇到想要取出沒列出的參數,可使用「 其餘參數 」的方式 …變數名稱。
1 | const nums = (...ary) => { |

- 使用其餘參數後,展開後可見原型 Property 一樣是陣列,可以使用所有陣列的方法,和
argument參數有些微不同。
➋ This 綁定的差異
箭頭函式沒有自己的 this,所以它的 this 會指向它外層。
範例 1.
1 | var myName = '全域'; |
解析:
因為箭頭函式沒有自己的 this,所以 setTimeout 裡的 this 就會指向它外層的 person 下的 myName。
範例 2.
1 | var myName = '全域'; |
解析:
callName調整成箭頭函式,因為箭頭函式沒有自己的this,所以會往外找外層的myName。- 答案:1、2 為
全域,3 為 window。
範例 3. this 不同,導致 DOM 的 this 也會指向不同位置
1 | // 使用傳統函式 |
this會指向p段落。

1 | // 使用箭頭函式 |
- 箭頭函式
this會指向window,因為箭頭函式沒有自己的this它會指向外層。

➌ 無法透過 call, apply, bind 重新給予 this
1 | const family = { |
- 傳統函式透過
call可把另外一段函式傳入,作為它的還是函式執行的this。 - 箭頭函式
family用call的方式傳入,this會指向全域,因為箭頭函式的this無法透過call,apply,bind重新給予。
❹ 箭頭函式不能當建構函式使用
範例 1. 查看傳統函式與箭頭函式的 prototype ( 原型 )
1 | const Fn = function (a) { |
- 這兩段拿來做建構函式使用,使用建構函式時會使用
prototype來新增一些方法,但因「 箭頭函式不具有prototype所以是不能拿來當建構函式使用 」。所以當ArrowFn要新建建構函式就會出現錯誤訊息Uncaught TypeError: ArrowFn is not a constructor。

關於建構式可參考:鐵人賽:JavaScript 建構式
❒ 箭頭函式常見問題
常見錯誤寫法 1
1 | const ArrFn = () => { |
此方式不能直接回傳物件實字,會顯示錯誤訊息:
Uncaught SyntaxError: Unexpected token '}’箭頭函式後的
{}是作為箭頭函式裡面的程式碼片段的範圍使用,並不是物件實字中使用的{}大括號。所以如果箭頭函式要回傳一個物件內容,須於{}外層加上()包覆 →({})。1
2
3
4
5// 正確寫法
const ArrFn = () => ({
data: 1,
});
console.log(ArrFn()); // 就可正確回傳裡面的物件
常見錯誤寫法 2. 判斷式後方不能接箭頭函式
1 | let num = 0; |
這種判斷式後方不能使用箭頭函式,會出現錯誤訊息
Uncaught SyntaxError: Malformed arrow function parameter list。正確寫法需使用傳統函式或是如上一個範例用
()包覆。1
2
3
4
5
6
7
8
9
10// 正確寫法 --1
// numFn 右方的 num 是假值(上方定義 num為0所以會直接執行後方函式),回傳函式表達式中的 1
let num = 0;
const numFn = num || function() { return 1; }
console.log(numFn());
// 正確寫法 --2
let num = 0;
const numFn = num || (() => 1);
console.log(numFn());
常見錯誤寫法 3
1 | const person = { |
會印出
undefined。因為箭頭函式沒有自己的this,callName使用箭頭函式裡面的this會指向全域,全域並沒有muName。所以如果要取得小明,callName就要使用傳統函式。1
2
3
4
5
6
7const person = {
myName: '小明',
callName: function (){
console.log(this.myName);
}
}
person.callName();
常見錯誤寫法 4. 箭頭函式不能作建構函式使用
1 | const Fn2 = function (a) { |
第一行使用傳統函式作建構函式使用。第二行在
Fn2函式的prototype下新增一個原型方法protoFn,這個原型方法使用建構函式來建立。console.log(newObj);可正確查到Fn2原型 (prototype) 下的protoFn方法。但實際在執行時console.log(newObj.protoFn());所得到的值會是空的。

為什麼無法得到
newObj下面的name,而是取到空值?主要是箭頭函式指向和傳統函式不同,所以
Fn2.prototype.protoFn裡的this指向是全域window而非第一行Fn2。1
2
3
4
5
6
7
8
9
10const Fn2 = function (a) {
this.name = a;
}
// 調整程式碼看看裡面的this
Fn2.prototype.protoFn = () => {
return this;
}
// 實體化
const newObj = new Fn2('函式');
console.log(newObj.protoFn()); // window正確寫法,把
Fn2.prototype.protoFn使用傳統函式來建構,可見this指向為第一行的Fn2。1
2
3
4
5
6
7
8
9const Fn2 = function (a) {
this.name = a;
}
Fn2.prototype.protoFn = function() {
return this;
}
// 實體化
const newObj = new Fn2('函式');
console.log(newObj.protoFn());
❒ 箭頭函式實戰用法
實戰 1. 搭配陣列方法
1 | // 陣列雙倍 |
map 很適合用在陣列裡所有的值都需要調整的時候,因為 map 會透過函式所回傳的值組成一個新的陣列。
實戰 2. 平均值 加總
1 | // 傳統函式寫法 |
average()此函式會將傳入的參數 (average(1, 2, 3, 4, 5)) 全部取出,我們使用arguments這個參數。由於arguments為類陣列沒有所有陣列的方法,所以Array.from使用將它轉為純陣列。
箭頭函式寫法
1 | const average = (...num) => num.reduce((acc, curr) => acc + curr, 0) / num.length; |
- 因為箭頭函式沒有
argument的方式,所以可使用其餘參數來解決無法取出沒有列出的參數問題。
實戰 3. 物件內 this
1 | // 傳統函式 |
- 記得先載入 jQuery CDN 才可運作
https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js
調整成箭頭函式
1 | // 箭頭函式寫法 |
- 箭頭函式沒有自己的
this,所以把success後方調整成箭頭函式後,裡面的this會指向外層作用域getData,而基於getData是由person呼叫所以this會指向person。success內原本的vm可修改成this,const vm = this;可刪除。
參考資訊
- JavaScript 必修篇 - 前端修練全攻略
- JavaScript 核心篇
- 鐵人賽:JavaScript 建構式
- JavaScript 陣列處理方法 [filter(), find(), forEach(), map(), every(), some(), reduce()]
- 30 SECONDS OF KNOWLEDGE