Arrow Functions อย่างละเอียด
ในบทที่แล้ว เราได้เรียนรู้เรื่อง Template Literals ซึ่งช่วยให้การจัดการ String ใน JavaScript ง่ายขึ้น ในบทนี้ เราจะมาเจาะลึกอีกหนึ่ง Feature ที่ทำให้โค้ด JavaScript กระชับและอ่านง่ายขึ้น นั่นคือ Arrow Functions
Arrow Functions คืออะไร?
Arrow Functions หรือ Lambda Functions เป็นวิธีเขียนฟังก์ชันใน JavaScript ที่สั้นและกระชับกว่า Function Expression แบบเดิม นอกจากนี้ Arrow Functions ยังมีพฤติกรรมที่แตกต่างออกไปในเรื่องของ this อีกด้วย
Syntax ของ Arrow Functions
รูปแบบพื้นฐานของ Arrow Function คือ:
(parameters) => expression
ถ้ามี parameter เดียว สามารถละเว้นวงเล็บได้:
parameter => expression
ถ้าไม่มี parameter เลย ต้องใช้วงเล็บ:
() => expression
ถ้า function body มีมากกว่าหนึ่ง statement หรือต้องการ return ค่าที่ซับซ้อน ต้องใช้วงเล็บปีกกา {} และระบุ return keyword:
(parameters) => {
// statements
return expression;
}
ตัวอย่าง:
// Function Expression แบบเดิม
const add = function(a, b) {
return a + b;
};
// Arrow Function
const addArrow = (a, b) => a + b;
console.log(add(5, 3)); // Output: 8
console.log(addArrow(5, 3)); // Output: 8
// Arrow Function ไม่มี parameter
const sayHello = () => console.log("Hello!");
sayHello(); // Output: Hello!
// Arrow Function มี parameter เดียว
const double = number => number * 2;
console.log(double(4)); // Output: 8
// Arrow Function ที่มีหลาย statements
const calculateArea = (width, height) => {
const area = width * height;
return area;
};
console.log(calculateArea(5, 10)); // Output: 50
ความแตกต่างกับ Function Expression
Arrow Functions มีความแตกต่างจาก Function Expression ในหลายประเด็น:
- Syntax: Arrow Functions มี syntax ที่สั้นและกระชับกว่า
thisBinding: นี่คือความแตกต่างที่สำคัญที่สุด Arrow Functions ไม่ได้สร้างthisbinding ของตัวเอง แต่จะใช้thisจาก scope ที่มันถูกสร้างขึ้น (lexicalthis) ในขณะที่ Function Expression จะสร้างthisbinding ใหม่ทุกครั้งที่ถูกเรียกใช้argumentsObject: Arrow Functions ไม่มีargumentsobject แต่สามารถใช้ rest parameters แทนได้- Cannot be used as constructors: Arrow Functions ไม่สามารถใช้เป็น constructor เพื่อสร้าง object ใหม่ได้
การใช้ this ใน Arrow Functions
ความเข้าใจเรื่อง this ใน Arrow Functions เป็นสิ่งสำคัญมาก เนื่องจากเป็นจุดที่แตกต่างจาก Function Expression อย่างชัดเจน
Function Expression (this binding แบบ dynamic):
function Person(name) {
this.name = name;
this.greet = function() {
console.log("Hello, my name is " + this.name);
};
}
const john = new Person("John");
john.greet(); // Output: Hello, my name is John
const greetFunc = john.greet;
greetFunc(); // Output: Hello, my name is undefined (หรือ window/global object name ใน browser)
ในตัวอย่างข้างต้น this ใน greetFunc() ไม่ได้อ้างอิงถึง object john อีกต่อไป เพราะมันถูกเรียกใช้ใน context ที่ต่างออกไป
Arrow Function (this binding แบบ lexical):
function Person(name) {
this.name = name;
this.greet = () => {
console.log("Hello, my name is " + this.name);
};
}
const john = new Person("John");
john.greet(); // Output: Hello, my name is John
const greetFunc = john.greet;
greetFunc(); // Output: Hello, my name is John (ยังคงอ้างอิงถึง object john)
ในตัวอย่างนี้ this ใน greetFunc() ยังคงอ้างอิงถึง object john เพราะ Arrow Function ใช้ this จาก scope ที่มันถูกสร้างขึ้น ซึ่งก็คือ scope ของ function Person
ตัวอย่างการใช้งาน this ใน Event Handlers:
<button id="myButton">Click Me</button>
const button = document.getElementById("myButton");
// Function Expression
button.addEventListener("click", function() {
console.log(this); // Output: <button id="myButton">Click Me</button> (element ที่เกิด event)
this.textContent = "Clicked!";
});
// Arrow Function
button.addEventListener("click", () => {
console.log(this); // Output: window (หรือ global object ใน browser)
// this.textContent = "Clicked!"; // Error: Cannot set properties of undefined (setting 'textContent' of null)
button.textContent = "Clicked!"; // ต้องอ้างอิง element โดยตรง
});
ในตัวอย่างนี้ Function Expression this จะอ้างอิงถึง element ที่เกิด event (button) ในขณะที่ Arrow Function this จะอ้างอิงถึง window object (หรือ global object ใน browser) ดังนั้นหากต้องการเข้าถึง element ที่เกิด event ใน Arrow Function ต้องอ้างอิง element โดยตรง
ข้อดีของ Arrow Functions
- โค้ดสั้นและกระชับ: ทำให้โค้ดอ่านง่ายและเขียนได้เร็วขึ้น
thisBinding ที่คาดเดาได้: ช่วยลดความสับสนในการใช้งานthisโดยเฉพาะใน callback functions
ข้อควรระวัง
- Arrow Functions ไม่เหมาะกับการใช้เป็น method ของ object ถ้าต้องการเข้าถึง
thisที่อ้างอิงถึง object นั้นๆ ควรใช้ Function Expression แทน - Arrow Functions ไม่เหมาะกับการใช้เป็น constructor
สรุป
Arrow Functions เป็นเครื่องมือที่มีประโยชน์ในการเขียน JavaScript ที่สั้น กระชับ และอ่านง่าย การเข้าใจเรื่อง this binding ใน Arrow Functions เป็นสิ่งสำคัญเพื่อให้ใช้งานได้อย่างถูกต้อง ในบทถัดไป เราจะมาเรียนรู้เรื่อง Default Parameters ในฟังก์ชัน ซึ่งเป็นอีกหนึ่ง Feature ที่ช่วยให้การเขียนฟังก์ชันมีความยืดหยุ่นมากขึ้น