JavaScript มี 2 วิธีหลักในการสร้างฟังก์ชัน: Function Declaration และ Function Expression ซึ่งแตกต่างกันในการ Hoisting และการใช้งาน
Function Declaration
function sayHello(name, age) {
document.write(name + " is " + age + " years old.");
}
คุณสมบัติ
- Hoisting: ฟังก์ชันถูกยกไปด้านบนสุดของ scope เรียกใช้ก่อนประกาศได้
- ต้องมีชื่อ (named function)
- Statement - ไม่ต้องมี semicolon ท้าย (แต่แนะนำให้ใส่)
Function Expression
// Anonymous function expression
var a = function() {
return 5;
};
// Named function expression
var a = function bar() {
return 5;
};
// Arrow function expression (ES6)
const add = (x, y) => x + y;
คุณสมบัติ
- No Hoisting: ต้องประกาศก่อนใช้งาน (ReferenceError ถ้าเรียกก่อน)
- สามารถเป็น Anonymous (ไม่มีชื่อ) หรือ Named
- Expression - ต้องมี semicolon ท้าย (ส่วนใหญ่)
- สามารถใช้เป็น IIFE, callback, argument ได้ทันที
ตารางเปรียบเทียบ
| คุณสมบัติ | Function Declaration | Function Expression |
|---|---|---|
| Hoisting | ✅ เต็มรูปแบบ | ❌ เฉพาะตัวแปร (var) / ไม่ได้ (let/const) |
| ชื่อฟังก์ชัน | บังคับ | เลือกได้ (anonymous/named) |
| ใช้ก่อนประกาศ | ได้ | ไม่ได้ (TDZ สำหรับ let/const) |
| ใช้เป็น Callback | ได้ (แต่ต้องประกาศก่อน) | ได้ (inline) |
| IIFE | ไม่ได้ (ต้องห่อในวงเล็บ) | ได้โดยตรง |
| this binding | Dynamic | Dynamic (ยกเว้น arrow function) |
ตัวอย่าง Hoisting
// Function Declaration - ใช้ได้
sayHello("John", 25); // "John is 25 years old."
function sayHello(name, age) {
console.log(name + " is " + age + " years old.");
}
// Function Expression - Error!
// sayHi("John"); // ReferenceError: Cannot access 'sayHi' before initialization
var sayHi = function(name) {
console.log("Hi " + name);
};
sayHi("John"); // OK - หลังประกาศแล้ว
Named Function Expression (NFE)
var factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1); // เรียกตัวเองได้ด้วยชื่อ 'fact'
};
// fact ไม่เข้าถึงได้จากนอก
// fact(5); // ReferenceError
// แต่เห็นใน stack trace ช่วย debug
factorial(5); // 120
Arrow Function (ES6)
// Expression only - ไม่มี declaration form
const add = (a, b) => a + b;
const greet = name => `Hello ${name}`;
// ไม่มี this, arguments, super, new.target ของตัวเอง
// เหมาะสำหรับ callback, functional programming
เมื่อไหร่ควรใช้ไหน?
- Function Declaration: ฟังก์ชันหลัก, utility functions, เมื่อต้องการ hoisting
- Function Expression: Callbacks, IIFE, Conditional definition, Methods ใน object
- Arrow Function: Short callbacks, ไม่ต้องการ this binding, Functional style