---
# System prepended metadata

title: 箭頭函式 JavaScript
tags: [JavaScript, 箭頭函式JavaScript]

---

# 箭頭函式 JavaScript
>整理者: Jung
來源:[MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions)、[箭頭函式](https://ithelp.ithome.com.tw/articles/10195669#:~:text=%E5%AE%83%E6%98%AFES6%20%E6%A8%99%E6%BA%96%E8%A3%A1,%E7%9A%84%E5%8F%AF%E9%96%B1%E8%AE%80%E6%80%A7%E6%8F%90%E9%AB%98%E3%80%82)
---
:::info
**箭頭函式運算式**（arrow function expression）擁有比函式運算式還簡短的語法。它沒有自己的 **this、arguments、super、new.target** 等語法。本函式運算式適用於非方法的函式，但不能被用作建構式（constructor）。
 :::
---
==JavaScript Demo: Functions =>==
``` javascript=
const materials = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

console.log(materials.map(material => material.length));
// expected output: Array [8, 6, 7, 9]
```
## 1.基本語法
``` javascript=
(參數1, 參數2, …, 參數N) => { 陳述式; } 

(參數1, 參數2, …, 參數N) => 表示式;
// 等相同(參數1, 參數2, …, 參數N) => { return 表示式; }

// 只有一個參數時,括號才能不加:
(單一參數) => { 陳述式; }
單一參數 => { 陳述式; }

//若無參數，就一定要加括號: () => { statements }
```
## 2.進階語法
```javascript=
// 用大括號將內容括起來，返回一個物件字面值表示法：
params => ({foo: bar}) 

// 支援其餘參數與預設參數
(param1, param2, ...rest) => { statements } 
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
statements } 

// 也支援 parameter list 的解構
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
```
## 3.說明
:::info
箭頭函式有兩個重要的特性：更短的函式寫法與 this 變數的非綁定。
:::
>---
==更短的函式寫法==
```javascript=
var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

// 這段函式會輸出[8, 6, 7, 9]這個陣列
elements.map(function(element) { 
  return element.length; 
}); 

// 上方這種一般的函式，可以被改寫成下方的箭頭函式
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 如果輸入的參數只有一個，我們可以移除掉外面的括號
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// 當箭頭函式裡的內容只有'return'的時候，我們可以拿掉return和外面的大括號
elements.map(element => element.length); // [8, 6, 7, 9]

// 在這個範例中，因為我們只需要length這個屬性，所以也可以使用解構賦值：
// 下方的'length'對應到我們想取得的屬性，而'lengthFooBArX'只是很普通的變數名稱,
// 可以被任意修改成你想要的名字
elements.map(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

// 上面這種解構賦值之後的參數也可以被改寫為下面這樣。但要注意的是，在這個範例中，
// 我們不是要指定'length'這個值給一個虛構的屬性，而是這個變數的名稱'length'本身就是
// 用來當成我們想從物件上取得的屬性
elements.map(({ length }) => length); // [8, 6, 7, 9]
```
==this 不分家==
:::info
在有箭頭函數之前，每個新函式是依據如何被呼叫來定義自己的 this 變數
:::


例如:
在建構子時是一個新物件
在呼叫嚴格模式函數時是 undefined
以物件方法呼叫時則為基礎物件
等等....
事實證明這對物件導向程式設計來說並不理想。
```javascript=
function Person() {
  // Person() 建構式將 this 定義為它自己的一個實體
  this.age = 0;

  setInterval(function growUp() {
    // 在非嚴格模式下, growUp() 函式把 this 定義為全域物件
    // (因為那是 growUp()執行的所在)，
    // 與 Person() 建構式所定義的 this 有所不同
    this.age++;
  }, 1000);
}

var p = new Person();
```
:::info
在 ECMAScript 3/5 裡面，有關 this 的問題，可以透過指派 this 值給可以關閉的變數解決。
:::

```javascript=
function Person() {
  var self = this; // 有些人喜歡 `that` 而不是 `self`. 
                   // 選好一種取法後始終如一
  self.age = 0;

  setInterval(function growUp() {
    // 這個 callback 參考 `self` 變數，為預期中的物件。
    self.age++;
  }, 1000);
}
```
:::info
或者透過 bind 函式來綁定 this 變數到指定函式（以上面為例，就是 growUp() 函式）。
箭頭函式並不擁有自己的 this 變數；使用的 this 值來自封閉的文本上下文，也就是說，箭頭函式遵循常規變量查找規則。因此，如果在當前範圍中搜索不到 this 變量時，他們最終會尋找其封閉範圍。
因此，在以下程式碼內，傳遞給 setInterval 的 箭頭函式中的this ，會與封閉函式的 this 值相同：
:::

```javascript=
function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 適切的參考了Person建構式所建立的物件
  }, 1000);
}

var p = new Person();
```

## 回傳物件字面值
:::warning
請注意只使用 params => {object:literal} 並不會按照期望般回傳物件字面值（object literal）。
:::
```javascript=
var func = () => { foo: 1 };               // Calling func() returns undefined!
var func = () => { foo: function() {} };   // SyntaxError: Unexpected token (
```
:::info
因為在大括弧（{}）裡面的文字會被解析為有序宣告（例如 foo 會被當作標記（label）、而不是物件的 key ）

要記得把物件字面值包在圓括弧內。
:::
```javascript=
var func = () => ({foo: 1});
var func = () => ({ foo: function() {} }); 
```
- [ ] [尚未完成...](/8I6RgWWdSaev4HBsoAfk6Q)有空再補
    - [ ] 說明
        - [ ] 和嚴格模式的關係
        - [ ] 由 call 與 apply 函式呼叫
        - [ ] 不綁定 arguments
        - [ ] 將箭頭函式撰寫為方法
        - [ ] 使用 new 運算子
        - [ ] 使用 prototype 屬性
        - [ ] 使用關鍵字 yield
    - [ ] 函式主體（Function body）
    - [ ] 回傳物件字面值
    - [ ] 換行
    - [ ] Parsing order
    - [ ] 更多範例
    - [ ] 規範
    - [ ] 瀏覽器相容性
###### tags: `JavaScript` `箭頭函式JavaScript`