ในบทความนี้จะพูดถึงเรื่องฟังก์ชัน Closure ในภาษา JavaScript แต่ก่อนอื่นจะขอทบทวนเรื่องตัวแปร (Variable) เสียก่อน สำหรับผู้อ่านที่เข้าใจเรื่องตัวแปรอยู่แล้วก็ข้ามไปอ่านข้างล่างได้เลยครับ
ตัวแปรในภาษา JavaScript สามารถแบ่งได้เป็น ตัวแปร local และตัวแปร global ซึ่งมีลักษณะดังนี้
1. ตัวแปร local เป็นตัวแปรที่ประกาศอยู่ภายในฟังก์ชัน และสามารถใช้ได้ภายในฟังก์ชันนั้นเท่านั้น ไม่สามารถเรียกจากภายนอกหรือฟังก์ชันอื่นได้ โดยมันจะถูกสร้างเมื่อฟังก์ชันถูกเรียกและถูกทำลายเมื่อจบฟังก์ชัน
ตัวอย่าง a เป็น ตัวแปร local:
|
2. ตัวแปร global เป็นตัวแปรที่สามารถเรียกใช้ได้จากทุกที่ และใช้งานได้ตลอดเวลาจนกว่าจะปิด Application (เช่น หน้าเว็บ)
ตัวอย่าง a เป็น ตัวแปร global:
|
ข้อควรระวังเกี่ยวกับตัวแปรใน JavaScript
|
หากเราต้องการสร้างฟังก์ชันสำหรับนับตัวเลขให้เพิ่มขึ้นเรื่อยๆทุกครั้งที่มีการเรียกฟังก์ชันนี้ เราจะทำอย่างไรดี??? มาลองดูตัวอย่างการสร้างฟังก์ชันแล้วเรียกใช้งานฟังก์ชันนี้ 3 ครั้งกัน
วิธีที่ 1 สร้างฟังก์ชันแบบปกติ แล้วให้มาใช้ตัวแปร global
|
วิธีนี้ผลลัพธ์ที่ได้จะได้ค่า counter เป็น 3 ซึ่งแน่นอนว่าถ้าเอาไปใช้งานก็ถือว่าเป็นโค้ดที่ทำงานได้ถูกต้อง แต่ปัญหาของวิธีนี้คือไม่ว่าใครก็สามารถมาเรียกใช้งานตัวแปร counter นี้ได้โดยตรง ซึ่งในทางการเขียนโปรแกรมแล้วนับว่าเป็นการเขียนโปรแกรมที่ไม่ดีเอาเสียเลย วิธีเขียนโปรแกรมที่ดีคือตัวแปร counter ควรจะเป็นตัวแปร local ที่เรียกผ่านได้ทางฟังก์ชัน count() เท่านั้น เพื่อป้องกันไม่ให้คนอื่นมาเปลี่ยนค่าตัวแปรนี้ได้
วิธีที่ 2 สร้าง counter เป็นตัวแปร local ด้วย
|
วิธีนี้มองผ่านๆ ผู้อ่านอาจจะคิดว่าหลังจากเรียกฟังก์ชัน count() ครบ 3 ครั้งแล้วจะได้ค่า counter เป็น 3 แต่ใน JavaScript นั้น ตัวแปร local และตัวแปร global ที่มีชื่อเดียวกันจะถือเป็นคนละตัว การเปลี่ยนค่าของตัวแปร counter ในฟังก์ชันจะไม่ส่งผลต่ออีกตัวแปร counter ที่อยู่นอกฟังก์ชัน ดังนั้นค่า counter ที่ได้ก็คือ 0 เหมือนเดิม เมื่อเป็นเช่นนั้นเราก็มาลองเอาตัวแปร global ทิ้ง แล้วเรียกฟังก์ชันจากภายในดู
วิธีที่ 3 สร้างฟังก์ชันซ้อนไว้ข้างใน
|
วิธีนี้ดูเหมือนจะใช้ได้ เพราะฟังก์ชัน plus() สามารถเข้าถึงตัวแปร couter ได้ แต่เราจะเรียกฟังก์ชัน plus() จากภายนอกได้อย่างไร?
หมายเหตุ: สำหรับคนที่งงว่าทำไมฟังก์ชัน plus() ถึงใช้งานตัวแปร counter ได้ ตรงจุดนี้ต้องทำความเข้าใจเรื่อง scope ก่อนครับ ในตอนที่ผมอธิบายเรื่องตัวแปร global ไปว่าเป็นตัวแปรที่เข้าถึงได้จากทุกที่ (global scopt) นั้น จริงๆแล้วถ้าพูดให้ละเอียดก็คือฟังก์ชันทุกฟังก์ชันสามารถเข้าถึงตัวแปรที่อยู่ scope เหนือมันได้ ซึ่งจะพบได้บ่อยตอนเขียนฟังก์ชันซ้อนฟังก์ชันอย่างในวิธีที่ 3 นี้ที่ฟังก์ชัน plus() สามารถเข้าถึงตัวแปร counter ที่เป็นตัวแปรของฟังก์ชันแม่จึงอยู่ scope เหนือมันได้ (parent scope)
ผู้อ่านคงจะเริ่มเกิดคำถามว่าวิธีที่ 1 ก็ไม่ดี วิธีที่ 2 ก็ใช้ไม่ได้ วิธีที่ 3 ก็ไม่รู้จะเรียกฟังก์ชันที่อยู่ข้างในฟังก์ชันอย่างไร แล้วจะให้ทำอย่างไร? ไม่ต้องกังวลไปครับ ปัญหานี้ JavaScript มีวิธีแก้ไขให้เราเรียบร้อยแล้ว นั่นก็คือ การใช้สิ่งที่เรียกว่า Closure นั่นเอง
Closure คือ ฟังก์ชันที่สามารถเข้าถึงตัวแปรใน parent scope ได้ แม้ว่าฟังก์ชันแม่นั้นจะจบไปแล้วก็ตาม ลองมาดูตัวอย่างฟังก์ชันนับเลขในวิธีที่ 4 กัน
วิธีที่ 4 สร้างฟังก์ชัน Closure
|
ในวิธีที่ 4 เราสร้างตัวแปร plus ขึ้่นมาแล้วกำหนดให้รับค่าที่คืนกลับมาจากฟังก์ชัน count() ซึ่งสิ่งที่คืนกลับมาก็คือฟังก์ชัน ทำให้ตัวแปร plus กลายเป็นฟังก์ชันนั่นเอง จากตัวอย่างนี้ จะเห็นได้ว่า Closure ทำให้ฟังก์ชันสามารถมีตัวแปร private ได้ และตัวแปรนี้จะไม่สามารถเรียกจากภายนอกฟังก์ชันได้โดยตรง ต้องเรียกผ่านฟังก์ชัน plus() เท่านั้น
เย้! สำเร็จแล้วครับ เท่านี้ก็เราก็สร้างฟังก์ชันนับเลขอย่างที่ต้องการได้แล้ว ต่อไปเรามาลองแสดงผล Hello World ออกทางหน้าจอด้วย Closure กัน
คราวนี้เราจะมาลองเขียนฟังก์ชันชื่อ show ซ้อนไว้ในฟังก์ชัน message เพื่อให้แสดงข้อความด้วย Closure กันครับ
1. เริ่มจากสร้างไฟล์ที่เราจะใช้เขียนโค้ดขึ้นมาก่อน โดยการคลิกขวาในโฟลเดอร์ที่เราต้องการแล้วเลือก New > Text Document เหมือนบทความก่อนหน้านี้ จากนั้นเปลี่ยนชื่อและนามสกุลไฟล์ ในที่นี้ตั้งชื่อว่า javascript04.html
2. เปิดไฟล์ด้วยโปรแกรมทีี่สามารถแก้ไขข้อความในไฟล์ได้ เช่น Notepad หรือ Notepad++ จากนั้นพิมพ์โค้ดต่อไปนี้ลงไป แล้วกด Save
อธิบายโค้ดส่วน JavaScript:
บรรทัดที่ 4 - 10 เป็นการสร้างฟังก์ชัน Closure
บรรทัดที่ 12 เป็นการสร้างตัวแปรชื่อ myFunction ให้รับค่าจากฟังก์ชัน message
3. ดับเบิ้ลคลิกที่ไฟล์ javascript04.html ที่เราเขียนโค้ดไว้แล้วในขั้นตอนที่ 2 จะเห็นหน้าต่างเว็บปรากฏขึ้นมา ให้ทดลองกดปุ่ม Click me จะเห็นว่ามีข้อความ Hello World ปรากฏขึ้นมา
เท่านี้เราก็จะสามารถเขียนโค้ด JavaScript เพื่อแสดงข้อความ Hello World ด้วย Closure ได้แล้ว ไม่งงใช่ไหมครับ? ถ้าอยากรู้เรื่องของ Closure เพิ่มเติมก็อ่านได้จาก [1] และ [2] นะครับ
สุดท้ายนี้ถ้าผู้อ่านอยากเรียนรู้เรื่อง JavaScript และเรื่องเกี่ยวกับ Web Programming อย่างลึกซึ้งก็ขอแนะนำคอร์ส Web Programming ของทาง EPT ครับ สามารถดูรายละเอียดคอร์สได้โดยคลิกที่นี่หรือติดต่อได้ที่ 085-350-7540
แล้วพบกันใหม่บทความหน้านะครับ
[1] https://www.w3schools.com/js/js_function_closures.asp
[2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Tag ที่น่าสนใจ: java c# vb.net python c c++ machine_learning web database oop cloud aws ios android
หากมีข้อผิดพลาด/ต้องการพูดคุยเพิ่มเติมเกี่ยวกับบทความนี้ กรุณาแจ้งที่ http://m.me/Expert.Programming.Tutor
085-350-7540 (DTAC)
084-88-00-255 (AIS)
026-111-618
หรือทาง EMAIL: NTPRINTF@GMAIL.COM