โคลเชอร์ (Closure) ในภาษา JavaScript
บทความนี้อธิบายเกี่ยวกับโคลเชอร์ (Closure) ในภาษา JavaScript
YouTube Video
โคลเชอร์ (Closure) ในภาษา JavaScript
ในภาษา JavaScript 'โคลเชอร์' เป็นหนึ่งในแนวคิดที่สำคัญและทรงพลังมาก ด้วยการเข้าใจโคลเชอร์ คุณจะได้รับความรู้ที่มีประโยชน์ในหลาย ๆ สถานการณ์ เช่น พฤติกรรมและขอบเขตการทำงานของฟังก์ชัน รวมถึงการประมวลผลแบบอะซิงโครนัสและการจัดการอีเวนต์ใน JavaScript ที่นี่เราจะอธิบายทุกอย่างอย่างละเอียด ตั้งแต่นิยามพื้นฐานของโคลเชอร์ ไปจนถึงตัวอย่างการใช้งานจริง
โคลเชอร์ คืออะไร?
โคลเชอร์ หมายถึงกลไกที่ฟังก์ชันสามารถเข้าถึงตัวแปรในขอบเขตที่ถูกประกาศ แม้จะเรียกใช้งานฟังก์ชันนั้นจากภายนอกขอบเขตดังกล่าว ด้วยการใช้โคลเชอร์ ฟังก์ชันสามารถ 'จดจำ' ตัวแปรภายนอกของตัวเองได้อย่างต่อเนื่อง
โคลเชอร์ ประกอบด้วยสององค์ประกอบหลักดังต่อไปนี้
-
นิยามฟังก์ชัน (ตัวฟังก์ชันเอง)
-
ขอบเขตที่นิยามฟังก์ชัน (ตัวแปรและฟังก์ชันอื่นๆ ที่อยู่นอกตัวฟังก์ชัน)
ในภาษา JavaScript โคลเชอร์ เป็นไปได้เพราะฟังก์ชันสามารถเข้าถึงตัวแปรในขอบเขตที่ฟังก์ชันถูกสร้างขึ้นมาได้
ตัวอย่างพื้นฐาน
ก่อนอื่น มาดูตัวอย่างพื้นฐานของโคลเชอร์ กัน ในโค้ดต่อไปนี้ outerFunction
จะให้ค่ากลับเป็นฟังก์ชันที่ชื่อว่า innerFunction
จุดที่สำคัญคือ innerFunction
สามารถเข้าถึงตัวแปร count
ที่ถูกประกาศในขอบเขตของ outerFunction
ได้
1function outerFunction() {
2 let count = 0;
3
4 function innerFunction() {
5 count++;
6 console.log(`Current count: ${count}`);
7 }
8
9 return innerFunction;
10}
11
12const counter = outerFunction();
13counter(); // Current count: 1
14counter(); // Current count: 2
15counter(); // Current count: 3
วิธีการทำงานของโคลเชอร์
อย่างที่เห็นในตัวอย่างด้านบน ตัวแปร count
จะยังคงอยู่ให้ innerFunction
ใช้งานได้แม้ว่า outerFunction
จะถูกเรียกและจบการทำงานไปแล้ว innerFunction
ยังคงสามารถเข้าถึงขอบเขตของ outerFunction
ได้ และทำให้ count
ถูกปรับค่าภายใน innerFunction
นี่คือกลไกพื้นฐานของโคลเชอร์
ฟังก์ชัน innerFunction
ถูกกำหนดให้กับตัวแปร counter
และเราสังเกตได้ว่าสถานะของ count
ยังคงอยู่แม้ว่า outerFunction
จะทำงานจบไปแล้ว เป็นเพราะ JavaScript 'จดจำ' ขอบเขตขณะที่ฟังก์ชันถูกสร้างขึ้นมาไว้นั่นเอง
การประยุกต์ใช้งาน: ใช้โคลเชอร์ เป็นตัวแปรส่วนตัว (Private Variable)
โคลเชอร์ สามารถนำมาใช้เป็น 'ตัวแปรส่วนตัว' แบบเดียวกับการเขียนโปรแกรมเชิงวัตถุ โดยปกติใน JavaScript สมาชิกของอ็อบเจกต์สามารถเข้าถึงได้โดยตรงจากภายนอก แต่ด้วยการใช้โคลเชอร์ เราสามารถป้องกันไม่ให้เข้าถึงหรือล้วงลึกตัวแปรภายในขอบเขตของฟังก์ชันจากภายนอกได้
ในตัวอย่างถัดไป ฟังก์ชัน createCounter
ใช้โคลเชอร์ เพื่อสร้างตัวนับ (Counter) และส่งกลับตัวนับที่มีตัวแปรส่วนตัวชื่อ count
1function createCounter() {
2 let count = 0;
3
4 return {
5 increment: function() {
6 count++;
7 console.log(`Count: ${count}`);
8 },
9 decrement: function() {
10 count--;
11 console.log(`Count: ${count}`);
12 },
13 getCount: function() {
14 return count;
15 }
16 };
17}
18
19const myCounter = createCounter();
20myCounter.increment(); // Count: 1
21myCounter.increment(); // Count: 2
22myCounter.decrement(); // Count: 1
23console.log(myCounter.getCount()); // 1
ในตัวอย่างนี้ count
อยู่ในขอบเขตของฟังก์ชัน createCounter
จึงไม่สามารถเข้าถึงโดยตรงจากภายนอกได้ แต่สามารถปรับค่าโดยใช้เมธอด increment
และ decrement
ได้ ดังนั้นการใช้โคลเชอร์ ก็ช่วยให้สามารถประยุกต์แนวคิดของตัวแปรส่วนตัวเข้ามาใช้ใน JavaScript ได้
ตัวอย่างการใช้โคลเชอร์ ในทางปฏิบัติ
การใช้ร่วมกับฟังก์ชัน Callback
โคลเชอร์ มักถูกใช้ร่วมกับฟังก์ชัน Callback เพื่อจัดการกับกระบวนการแบบอะซิงโครนัส ตัวอย่างเช่น มาดูตัวอย่างที่ใช้ตัวจับเวลา (Timer)
1function startTimer(duration) {
2 let timeLeft = duration;
3
4 function countdown() {
5 console.log(`Time left: ${timeLeft} seconds`);
6 timeLeft--;
7
8 if (timeLeft >= 0) {
9 setTimeout(countdown, 1000);
10 }
11 }
12
13 countdown();
14}
15
16startTimer(5);
17// Time left: 5 seconds
18// Time left: 4 seconds
19// Time left: 3 seconds
20// Time left: 2 seconds
21// Time left: 1 second
22// Time left: 0 seconds
ในตัวอย่างนี้ ฟังก์ชัน countdown
จะเข้าถึงตัวแปร timeLeft
ที่อยู่ในขอบเขตของ startTimer
ด้วยวิธีนี้ โคลเชอร์ มีประโยชน์มากสำหรับการทำงานแบบอะซิงโครนัส เช่น ตัวจับเวลา เพราะสามารถเก็บสถานะของตัวแปรไว้ได้ตลอดเวลา
Event Handler (ตัวจัดการเหตุการณ์)
โคลเชอร์ ก็สะดวกต่อการตั้งค่า Event Handler เช่นกัน ในตัวอย่างต่อไปนี้ โคลเชอร์ ถูกใช้เพื่อบันทึกจำนวนครั้งที่ปุ่มถูกคลิก
1function setupClickCounter(buttonId) {
2 let clickCount = 0;
3
4 const button = document.getElementById(buttonId);
5 button.addEventListener('click', function() {
6 clickCount++;
7 console.log(`Button clicked ${clickCount} times`);
8 });
9}
10
11setupClickCounter('myButton');
กรณีนี้ค่า clickCount
จะเพิ่มขึ้นทุกครั้งที่คลิก และค่าจะถูกเก็บเอาไว้ ด้วยการใช้โคลเชอร์ คุณสามารถกำหนดตัวนับแยกสำหรับแต่ละปุ่มได้
สรุป
โคลเชอร์ เป็นแนวคิดที่แสดงถึงความยืดหยุ่นและพลังของ JavaScript โคลเชอร์ เก็บรักษาตัวแปรที่ถูกห่อหุ้มในขอบเขตฟังก์ชันไว้ และอนุญาตให้เข้าถึงหรือจัดการตัวแปรนั้นผ่านฟังก์ชันที่เข้าถึงได้จากภายนอก ด้วยความเข้าใจและการใช้กลไกนี้ คุณจะสามารถพัฒนาทักษะในการเขียนโค้ด JavaScript ได้อย่างก้าวหน้า
โคลเชอร์ ถูกนำไปใช้ในสถานการณ์ต่าง ๆ เช่น การจัดการเหตุการณ์ การประมวลผลแบบอะซิงโครนัส หรือแม้แต่การสร้างการจำลองแบบเชิงวัตถุ (OOP) ใน JavaScript
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย