Closure คือฟังก์ชันที่ "จับ" (Capture) ตัวแปรจาก Lexical Scope รอบนอกไว้ ใช้ได้แม้ Scope นั้นจบการทำงานแล้ว เป็นพื้นฐานของการสร้าง Private State ใน JavaScript
ตัวอย่างโค้ด
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Closure Privacy</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
.result { font-size: 18px; font-weight: 500; color: blueviolet; }
</style>
</head>
<body>
<h1>ใช้ Closures สร้าง Privacy</h1>
<div class="result"></div>
<br />
<button class="Btn">Increment</button>
<button class="Btn">Access</button>
<h3>คลิกปุ่ม Increment เพื่อเพิ่มค่า หรือ Access เพื่อลองเข้าถึงตัวแปรโดยตรง</h3>
<script>
const resEle = document.querySelector(".result");
const BtnEle = document.querySelectorAll(".Btn");
// Factory Function สร้าง Counter
function createCounter() {
let count = 0; // Private Variable - ตกอยู่ใน Closure
return {
increment: () => ++count,
decrement: () => --count,
getValue: () => count
};
}
const counter = createCounter();
BtnEle[0].addEventListener("click", () => {
resEle.innerHTML = counter.increment();
});
BtnEle[1].addEventListener("click", () => {
try {
resEle.innerHTML = count; // Error: count is not defined
} catch (err) {
resEle.innerHTML = err.message; // "count is not defined"
}
});
</script>
</body>
</html>
Closure Pattern สำหรับ Privacy
// 1. Module Pattern (Classic)
const Counter = (function() {
let count = 0;
return {
inc: () => ++count,
dec: () => --count,
get: () => count
};
})();
// 2. Factory Function (Recommended)
function createCounter(initial = 0) {
let count = initial;
return {
inc() { return ++count; },
dec() { return --count; },
get() { return count; },
// Private method (ไม่ expose ออกไป)
_reset() { count = initial; }
};
}
// 3. Class with Private Fields (ES2022)
class Counter {
#count = 0; // True Private
inc() { return ++this.#count; }
dec() { return --this.#count; }
get() { return this.#count; }
}
Use Cases จริง
- Data Encapsulation: ซ่อน Implementation Details
- Stateful Functions: ฟังก์ชันที่จำ State ระหว่างการเรียก
- Memoization/Caching: จำผลลัพธ์ไว้ใช้ซ้ำ
- Event Handlers: เก็บข้อมูลเฉพาะ Event
ผลลัพธ์
- คลิก Increment หลายครั้ง: ค่าเพิ่มขึ้น 1, 2, 3, 4...
- คลิก Access: Error "count is not defined" - เข้าถึง Private ไม่ได้