Function Declaration and Arrow Function


ในการเขียนโค้ด TypeScript เราสามารถประกาศฟังก์ชันได้สองแบบหลักๆ คือ Function Declaration และ Arrow Function (หรือ Fat Arrow Function) ซึ่งมีวิธีการเขียนและคุณสมบัติที่แตกต่างกันเล็กน้อย

Function Declaration

Function Declaration เป็นวิธีการประกาศฟังก์ชันแบบดั้งเดิมใน JavaScript และ TypeScript โดยใช้คีย์เวิร์ด function ตามด้วยชื่อฟังก์ชัน พารามิเตอร์ และโค้ดที่ต้องการให้ทำงานภายในฟังก์ชัน

ตัวอย่าง Function Declaration ใน TypeScript:

function greet(name: string): string {
  return `Hello, ${name}!`;
}

console.log(greet('John')); // Output: "Hello, John!"

ในตัวอย่างนี้ ฟังก์ชัน greet รับพารามิเตอร์ name ที่เป็น string และ return ค่าเป็น string ที่มีข้อความทักทายพร้อมชื่อที่รับเข้ามา

Arrow Function (Fat Arrow Function)

Arrow Function เป็นวิธีการประกาศฟังก์ชันแบบใหม่ที่ถูกเพิ่มเข้ามาใน ECMAScript 6 (ES6) และสามารถใช้ใน TypeScript ได้ Arrow Function มีไวยากรณ์ที่กระชับกว่า Function Declaration และมีคุณสมบัติพิเศษบางอย่าง

ตัวอย่าง Arrow Function ใน TypeScript:

const add = (a: number, b: number): number => {
  return a + b;
};

console.log(add(2, 3)); // Output: 5

ในตัวอย่างนี้ ฟังก์ชัน add ถูกประกาศโดยใช้ Arrow Function โดยรับพารามิเตอร์ a และ b ที่เป็น number และ return ผลรวมของ a และ b

ความแตกต่างระหว่าง Function Declaration และ Arrow Function

หนึ่งในความแตกต่างที่สำคัญระหว่าง Function Declaration และ Arrow Function คือการจัดการกับค่าของ this ภายในฟังก์ชัน

ตัวอย่างการใช้ this ใน Function Declaration:

class Counter {
  private count = 0;

  increment() {
    setTimeout(function() {
      this.count++;
      console.log(this.count);
    }, 1000);
  }
}

const counter = new Counter();
counter.increment(); // Output: NaN

ในตัวอย่างนี้ เมื่อเรียกใช้ฟังก์ชัน increment() ค่าของ this ภายในฟังก์ชัน callback ของ setTimeout จะไม่ใช่ instance ของ Counter แต่จะเป็น this ของ window (ในกรณีที่รันบน browser) หรือ undefined (ในกรณีที่ใช้ strict mode) ทำให้เกิด NaN เมื่อพยายามเข้าถึง this.count

ตัวอย่างการใช้ Lexical this ใน Arrow Function:

class Counter {
  private count = 0;

  increment() {
    setTimeout(() => {
      this.count++;
      console.log(this.count);
    }, 1000);
  }
}

const counter = new Counter();
counter.increment(); // Output: 1

ในตัวอย่างนี้ เมื่อใช้ Arrow Function เป็นฟังก์ชัน callback ใน setTimeout ค่าของ this ภายใน Arrow Function จะเป็น this ของ surrounding context นั่นคือ instance ของ Counter ทำให้สามารถเข้าถึง this.count ได้อย่างถูกต้องและเพิ่มค่า count ได้ตามที่ต้องการ

Arrow Function จะใช้ Lexical this ซึ่งจะคงค่า this ของ surrounding context ไว้ ในขณะที่ Function Declaration จะมีค่า this ที่ถูกกำหนดโดยวิธีที่ฟังก์ชันถูกเรียก ซึ่งอาจทำให้เกิดปัญหาได้หากไม่ระวัง

สรุปได้ว่า ทั้ง Function Declaration และ Arrow Function เป็นเครื่องมือสำคัญในการประกาศฟังก์ชันใน TypeScript โดย Arrow Function จะใช้ Lexical this ซึ่งเหมาะสำหรับกรณีที่ต้องการเข้าถึง this ของ surrounding context ส่วน Function Declaration จะมีค่า this ที่ถูกกำหนดโดยวิธีที่ฟังก์ชันถูกเรียก ซึ่งเหมาะสำหรับกรณีที่ต้องการให้ฟังก์ชันมีค่า this ของตัวเอง การเลือกใช้งานขึ้นอยู่กับความต้องการและบริบทของโค้ดเป็นหลัก

ในการพัฒนา Next.js App ด้วย TypeScript นักพัฒนามักใช้ Arrow Function ในการเขียน React Components และ Event Handlers เพื่อใช้ประโยชน์จาก Lexical this และไวยากรณ์ที่กระชับ แต่ในบางกรณีที่ต้องการประกาศฟังก์ชันแบบทั่วไปหรือต้องการควบคุมค่าของ this ก็สามารถใช้ Function Declaration ได้เช่นกัน

Last updated