JavaScript
Functions
Function declaration
เรียนรู้วิธีประกาศฟังก์ชันด้วย function keyword การเรียกใช้ฟังก์ชัน และ hoisting ก่อนลงลึกเรื่อง parameter และ return ในบทถัดไป
ฟังก์ชันคืออะไร
ฟังก์ชัน (function) คือกลุ่มคำสั่งที่ถูกตั้งชื่อและเก็บไว้ใช้ซ้ำได้ แทนที่จะเขียนคำสั่งเดิมซ้ำหลาย ๆ รอบ เราเขียนโค้ดไว้ในฟังก์ชันครั้งเดียว แล้วเรียกใช้ชื่อฟังก์ชันเมื่อต้องการให้คำสั่งนั้นทำงานอีก ประโยชน์หลักของฟังก์ชันมี 3 ข้อ: - **ใช้ซ้ำ**: เขียนครั้งเดียว เรียกใช้ได้หลายครั้ง - **ตั้งชื่อให้กลุ่มคำสั่ง**: ชื่อฟังก์ชันบอกได้ว่าโค้ดส่วนนี้ทำอะไร โดยไม่ต้องอ่านทุกบรรทัด - **จัดระเบียบโค้ด**: แยกงานใหญ่ออกเป็นฟังก์ชันย่อย ทำให้อ่านและแก้ไขง่ายขึ้น
ประกาศฟังก์ชัน showMessage แล้วเรียกใช้ — ฟังก์ชันยังไม่ทำงานจนกว่าจะถูกเรียก
function showMessage() {
console.log("เริ่มต้นเรียน JavaScript");
}
showMessage(); // ตรงนี้ฟังก์ชันถึงจะทำงานจากตัวอย่าง: `function showMessage() { ... }` คือการประกาศฟังก์ชัน (ยังไม่รัน) และ `showMessage()` คือการเรียกใช้ฟังก์ชัน (ถึงจะรันคำสั่งข้างใน) สองอย่างนี้แยกจากกัน — ประกาศก่อน แล้วค่อยเรียกใช้ทีหลัง
โครงสร้าง Function Declaration
Function Declaration ประกอบด้วย 4 ส่วนหลักที่ต้องมีครบทุกครั้ง:
| ส่วน | ตัวอย่าง | หน้าที่ |
|---|---|---|
| `function` keyword | `function` | บอก JavaScript ว่านี่คือการประกาศฟังก์ชัน |
| ชื่อฟังก์ชัน | `showMessage` | ชื่อสำหรับเรียกใช้ในภายหลัง |
| วงเล็บ `()` | `()` | ต้องมีทั้งตอนประกาศและตอนเรียกใช้เสมอ |
| body `{ }` | `{ ... }` | โค้ดทั้งหมดที่จะรันเมื่อฟังก์ชันถูกเรียก |
function ชื่อฟังก์ชัน() {
// คำสั่งที่อยากเก็บไว้ใช้ซ้ำ
}
// เรียกใช้
ชื่อฟังก์ชัน();**การตั้งชื่อฟังก์ชัน** ควรใช้ camelCase และสื่อความหมายว่าฟังก์ชันทำอะไร: - `showMenu` — ชัดเจนว่าทำอะไร (แสดงเมนู) - `calculateTotal` — ชัดเจนว่าคำนวณผลรวม - `printReport` — ชัดเจนว่าพิมพ์รายงาน เริ่มต้นด้วยตัวอักษร ห้ามมีช่องว่าง ห้ามใช้ตัวเลขนำหน้า
การเรียกใช้ฟังก์ชัน
การประกาศฟังก์ชันอย่างเดียวไม่ทำให้โค้ดในฟังก์ชันทำงาน JavaScript แค่จำไว้ว่ามีฟังก์ชันชื่อนี้อยู่ ฟังก์ชันจะทำงานก็ต่อเมื่อเรา**เรียกใช้**ด้วยชื่อฟังก์ชันตามด้วย `()`
function showMenu() {
console.log("หน้าแรก");
console.log("บทเรียน");
console.log("แบบฝึกหัด");
}
showMenu(); // เรียก 1 ครั้ง → แสดง 3 บรรทัดเมื่อเรียก `showMenu()` ครั้งเดียว คำสั่งทั้ง 3 บรรทัดในฟังก์ชันจะรันตามลำดับ **เรียกซ้ำได้ไม่จำกัดครั้ง** — ทุกครั้งที่เรียกฟังก์ชัน คำสั่งใน body จะถูกรันใหม่ทั้งหมด:
function showMenu() {
console.log("หน้าแรก");
console.log("บทเรียน");
console.log("แบบฝึกหัด");
}
showMenu(); // ครั้งที่ 1 → 3 บรรทัด
console.log("---");
showMenu(); // ครั้งที่ 2 → 3 บรรทัดอีกใช้ฟังก์ชันจัดกลุ่มคำสั่งตามหน้าที่
เมื่อโค้ดมีหลายขั้นตอน การตั้งชื่อฟังก์ชันให้สื่อถึงหน้าที่ของแต่ละส่วนจะช่วยให้อ่านโค้ดจากบนลงล่างแล้วเข้าใจภาพรวมทันที โดยไม่ต้องอ่านรายละเอียดทุกบรรทัด
function showHeader() {
console.log("=== เริ่มบทเรียน ===");
}
function showFooter() {
console.log("=== จบบทเรียน ===");
}
// อ่านจากบนลงล่างก็เห็นภาพรวมทันที
showHeader();
console.log("กำลังเรียน Function Declaration");
showFooter();การตั้งชื่อฟังก์ชันแบบนี้เรียกว่า **self-documenting code** — ชื่อฟังก์ชันทำหน้าที่เป็นเอกสารในตัวมันเอง ทำให้คนอ่าน (รวมถึงตัวเราในอีก 2 สัปดาห์ข้างหน้า) เข้าใจโค้ดได้เร็วขึ้น
Hoisting — เรียกฟังก์ชันก่อนบรรทัดประกาศได้
Function Declaration มีความสามารถพิเศษที่เรียกว่า **hoisting** — JavaScript จะยกการประกาศฟังก์ชันขึ้นไปด้านบนสุดของ scope โดยอัตโนมัติก่อนเริ่มรันโค้ด ผลคือ: **เราสามารถเรียกใช้ฟังก์ชันก่อนบรรทัดที่ประกาศฟังก์ชันได้**
// เรียกฟังก์ชันก่อนบรรทัดประกาศ
showReady();
function showReady() {
console.log("พร้อมทำงาน");
}
// output: พร้อมทำงานโค้ดด้านบนทำงานได้ปกติ — ถึงแม้ `showReady()` จะอยู่ก่อน `function showReady() { ... }` ก็ตาม **ทำไมถึงเป็นแบบนี้**: JavaScript engine อ่านโค้ดทั้งหมดก่อนรัน และจดจำชื่อฟังก์ชันทั้งหมด (hoist) ไว้ล่วงหน้า เมื่อถึงบรรทัดเรียกใช้จึงรู้จักฟังก์ชันนั้นแล้ว ฟังก์ชันจึงทำงานได้ **ข้อควรรู้**: hoisting เป็นพฤติกรรมที่เกิดเฉพาะกับ Function Declaration เท่านั้น ฟังก์ชันแบบอื่น (Function Expression และ Arrow Function) ที่จะเรียนในบทถัดไปไม่มีคุณสมบัตินี้
ข้อผิดพลาดที่พบบ่อย
- **ลืมวงเล็บ `()` ตอนเรียกใช้**: การเขียนแค่ `showMenu` โดยไม่มี `()` จะไม่เรียกฟังก์ชัน — JavaScript จะมองเป็นแค่ชื่อตัวแปรที่ชี้ไปที่ฟังก์ชัน แต่ไม่รันมัน
- **ประกาศฟังก์ชันใน `if` หรือ loop**: การประกาศ `function` ใน `if` หรือ loop จะถูก hoist ออกไปนอกบล็อกเสมอ — ฟังก์ชันจะมองเห็นได้จากนอก `if`/loop ซึ่งขัดกับที่ตาเห็น ควรประกาศฟังก์ชันไว้นอกบล็อกทุกครั้ง
- **ตั้งชื่อฟังก์ชันไม่สื่อความหมาย**: ชื่อแบบ `doIt()`, `run()`, `x()` ทำให้อีก 2 สัปดาห์ต่อมาเราอ่านโค้ดตัวเองไม่รู้เรื่อง ควรตั้งชื่อให้บอกได้ว่า function นี้ทำอะไร
- **ประกาศฟังก์ชันซ้ำชื่อ**: ถ้าประกาศฟังก์ชันชื่อซ้ำกัน ตัวหลังจะทับตัวแรก — ทำให้ฟังก์ชันแรกหายไป
- **เข้าใจผิดว่าประกาศแล้วรันทันที**: การประกาศฟังก์ชัน (บรรทัด `function ...`) ไม่รัน body — ต้องเรียกใช้ด้วย `()` เท่านั้น body จึงจะทำงาน