10 เรื่องของ ES6 ที่คุณควรรู้ไว้ (ตอนที่ 4 Arrow Functions)
Tags: javascript, es5, es6
Published: 2022-07-17 16:28:12

---
title: 10 เรื่องของ ES6 ที่คุณควรรู้ไว้ (ตอนที่ 4 Arrow Functions)
published: true
description: 
tags: javascript, es5, es6
//cover_image: https://direct_url_to_image.jpg
---

## 10 เรื่องของ ES6 ที่คุณควรรู้ไว้ (ตอนที่ 4 Arrow Functions)

สวัสดีครับท่านผู้สนใจในการเขียนโปรแกรมด้วยภาษา `JavaScript` ทุกท่าน บทความนี้เป็นตอนที่ 4 ในซี่รีย์ชุด [10 เรื่องของ ES6 ที่คุณควรรู้ไว้](https://dev.to/iammen/10-es6-1-default-function-parameter-2ej) ครั้งนี้ผมจะมาแบ่งปันกับทุกๆ คนในเรื่อง Arrow Functions กัน

Arrow function เป็นรูปแบบ syntax ที่ใช้งานสำหรับ function โดยเฉพาะ ตัว syntax ที่ใช้จะมีลักษณะคล้ายลูกศรคือ `=>` ประโยชน์หลักๆ ของมันก็คือ ทำให้รูปแบบการเขียน function ใน `JavaScrip` ดูสั้นกระชับมากขึ้น รวมทั้งความสามารถในการจัดการกับ `this` keyword ของมันก็ทำให้เราทำความเข้าใจได้ง่ายขึ้นเช่นกัน มาลองดูตัวอย่างการใช้งานของมันกันเลย


###เขียน function ให้กระชับด้วย Arrow function

ตัวอย่างที่กำลังจะแสดงเราจะประกาศตัวแปร array ชื่อ *aHero* ซึ่งมันจะเก็บข้อมูล string แบบตัวพิมพ์เล็กทั้งหมดเอาไว้ 1 ชุด จากนั้นเราจะลองใช้งาน arrow function ร่วมกับ `map` method (`map` เป็น built-in method ของ Array object ใน `JavaScript`) เพื่อเปลี่ยนข้อความใน array เป็นตัวพิมพ์ใหญ่ทั้งหมดด้วย `toUpperCase` method อีกที อธิบายมากเดี๋ยวจะงง มาดูตัวอย่างกันดีกว่า

```javascript
// ประกาศตัวแปร array
var aHero = ['superman', 'spiderman', 'batman'];

// ใช้ map method ใน ES5 เดิม
var es5Output = aHero.map(function(h) { 
  return h.toUpperCase()
});

// ใช้ map method ใน ES6 ด้วย arrow function
var es6Output = aHero.map( h => h.toUpperCase() );

console.log(es5Output);  // ['SUPERMAN', 'SPIDERMAN', 'BATMAN']
console.log(es6Output);  // ['SUPERMAN', 'SPIDERMAN', 'BATMAN']
```

การทำงานของตัวอย่างนี้ `map` method จะรับ parameter เข้าไป 1 ตัวซึ่งคือฟังก์ชั่นแบบไม่มีชื่อหรือที่เรียกกันว่า anonymous function และ function นี้ก็จะรับ parameter อีก 1 ตัวที่เราตั้งชื่อว่า *h* ซึ่งตัวแปร *h* นี้จะเก็บข้อมูล string ซึ่งก็จะคือข้อมูลในแต่ละตำแหน่งที่เก็บอยู่ในตัวแปร *aHero* นั้นเอง สุดท้ายในส่วน body ของ function นี้ก็จะทำการเปลี่ยนข้อความ string ให้เป็นตัวพิมพ์ใหญ่ด้วย `toUpperCase` method และทำการคืนค่ามันออกมา

>
> จะสังเกตว่าเมื่อเราใช้ arrow function เราจะสามารถละการเขียน function และ `return` syntax ไปได้เลย ทำให้ code ที่ได้ดูสั้นกระชับมากขึ้น
>

ต่อไปมาลองดูตัวอย่างการใช้งาน arrow function แบบใช้ parameter หลายๆ ตัวกันบ้าง


```javascript
// แบบ ES5
var es5Multiply = function(x, y) {
 return x * y;
}
alert(es5Multiply(2, 5)); // 10

// แบบ ES6
var es6Multiply = (x, y) => { return x * y };
alert(es6Multiply(4, 10)); // 40
```


###`this` keyword ใน `JavaScript`

จากที่ทราบกันว่าในทุกๆ function จะมีการประกาศ `this` ของมันเองขึ้นมาใช้งาน ซึ่งถ้าใครเคยผ่านการเขียนโปรแกรมด้วยภาษา `C#` หรือ `Java` มาก่อนก็คงพอจะเข้าใจว่า `this` keyword นี้จะเปรียบเสมือนเป็นตัวแทนของ object ที่กำลังทำงานอยู่ ทำให้เราสามารถใช้ `this` เพื่อเข้าถึงตัวแปรหรือว่า function ของ object นั้นได้

แต่แนวคิดนี้กลับใช้ไม่ได้กับเจ้า `this` ใน `JavaScript` เพราะ `this` ใน `JavaScript` ที่ถูกสร้างขึ้นมานั้นจะมีสถานะการทำงานขึ้นอยู่กับ Execution context ก่อนหน้าที่ function นั้นถูกเรียกใช้งาน อธิบายแบบนี้คงจะต้องงงกันเป็นแน่ มาดูตัวอย่างกันดีกว่า

```javascript
function displyContext() {
 this.name = 'จุดนี้คือ global context';
 console.log(this);
}

// ผลลัพธ์ที่ได้คือจะพิมพ์ this ในตำแหน่ง window object
// เพราะ function ถูกเรียกใช้งานในระดับ global context
displyContext();

var obj = {
 name: 'จุดนี้คือ function context',
 displyContext: function() {
  console.log(this);
 }
};

// ผลลัพธ์ที่ได้คือจะพิมพ์ this ในตำแหน่งของตัวแปร obj
// เพราะ function ถูกเรียกใช้งานภายในตัวแปร obj
obj.displyContext();

var global = obj.displayContext;
global();
```

จากตัวอย่างด้านบน หลังจาก function ชื่อ *displyContext* ถูกเรียกใช้งานเราจะได้ผลลัพธ์แรกที่ถูกพิมพ์ออกมาเป็น `this` ในระดับ window object ซึ่งก็เพราะว่า execution context ก่อนหน้าที่ function นี้จะถูกเรียกใช้งานมันคือ global context ซึ่งบน browser ตัว global context ที่ว่าก็คือ window object นั้นเอง ทำให้ `this` ที่ถูกสร้างขึ้นจะอ้างถึง window object ในทันที ทีนี้ลองมาเดาดูสิครับว่าตัวแปร *name* ที่ประกาศภายใน function นี้จะอยู่ภายใต้ window object ด้วยหรือไม่ ไปทดลองกันดูนะครับ

ลำดับถัดมาเป็นการเรียก function ชื่อ *displyContext* เหมือนเดิม แต่คร่าวนี้ *displyContext* จะทำงานเหมือนเป็น method ของ object ที่ชื่อว่า *obj* อีกที ซึ่งหลังจากที่ function นี้ถูกใช้งาน เราจะได้ผลลัพธ์ที่พิมพ์ `this` ออกมาในระดับ obj object แทน ไม่ใช่ window object แล้วนะครับตอนนี้ เหตุที่เป็นแบบนี้ก็เพราะว่า execution context ก่อนหน้าที่ *displyContext* จะถูกเรียกใช้งานก็คือตัว obj object นั่นเอง

และสุดท้ายคือการสร้างตัวแปรขึ้นมาอีกตัวชื่อ *global* แล้วกำหนดตำแหน่งอ้างอิงของ *displyContext* ของตัวแปร *obj* ให้กับมัน จากนั้นก็ทำการเรียกใช้งานฟังก์ชั่น *global* แต่คราวนี้ execution context จะเปลี่ยนจาก obj object เป็น window object เช่นเดิม แน่นอนครับสาเหตุก็เพราะ execution context ก่อนหน้าที่จะเรียกฟังก์ชั่น *global* ใช้งานคือ window object นั่นเอง

###การใช้งาน `this` keyword ในยุคก่อน Arrrow function

จากตัวอย่างก่อนหน้าคุณคงเห็นแล้วว่า การใช้งาน `this` keyword ได้อย่างถูกต้องนั้น เราจำเป็นต้องเข้าใจในเรื่อง execution context กันเสียก่อน ไม่อย่างนั้นอาจจะทำให้เกิดความสับสนได้ มาลองดูอีกตัวอย่างหนึ่งที่จะแสดงถึงปัญหาของการใช้งาน `this` keyword กัน

```javascript
function MyHero() {
 // ณ จุดนี้เป็น MyHero constructor จะเป็นจุดที่สร้าง this ขึ้นมาใช้งาน 
 // เพื่อทำหน้าที่แทน MyHero object เอง
 this.fight = 0;

 setInterval(function fighting() {
  // this นี้จะอ้างอิงกับ window object
  this.fight++;
 }, 5000);
}

var hero = new MyHero();
```

ใน non-strict mode นั้น เมื่อฟังก์ชั่น *fighting* ถูกเรียกใช้งานมันก็จะสร้าง `this` ของมันเองขึ้นมาใช้งาน แต่ `this` ที่มันสร้างมานี้จะอ้างอิงกับ window object แทนไม่ใช่ `this` ของตัวแปร *MyHero* อย่างที่คุณคิดกัน จากปัญหานนี้ใน `ES5` จึงก็มีเทคนิคการจัดการกับ `this` เพื่อใช้ในการแก้ปัญหานี้ มาดูตัวอย่าง

```javascript
function MyHero() {
 var that = this; // กำหนด this ให้กับตัวแปร that
 that.fight = 0;

 setInterval(function fighting() {
  // เมื่อ fighting() ทำงานมันก็จะสามารถใช้งานตัวแปร that 
  // ซึ่งจริงๆ ก็คือ this ของ MyHero ได้อย่างถูกต้อง
  that.fight++;
  }, 5000);
}
```

###Arrow function ผู้พิชิต `this` keyword

หลังจาก Arrow function ได้ถูกนำมาให้งานใน `ES6` ปัญหาน่าปวดหัวต่างๆ เหล่านี้กลับหมดไปทันที เนื่องจากมันมีความฉลาดพอที่จะรู้ว่า execution context ที่เราต้องการใช้งานจริงนั้นคือจุดไหน มาดูตัวอย่างเลย

```javascript
function MyHero(){
 this.fight = 0;

 setInterval(() => {
  // this ที่ถูกเรียกใช้งานนี้จะอ้างอิงกับ MyHero object ในทันที
  this.fight++;
 }, 5000);
}

var h = new MyHero();
```


เอาละครับคงพอเห็นแนวทางการใช้งานและประโยชน์ต่างๆ ของ Arrow function กันบ้างแล้วนะ บทความนี้ก็คงขอจบไว้เพียงเท่านี้ก่อน ขอให้ติดตามและสนุกกับการเรียนรู้กันต่อไปนะครับ