Namespacing in JavaScript

Namespacing
Namespacing

เคยสงสัยกันไหมครับว่าทำไมเราจึงครวที่จะต้องกำหนด Namespace ใน JavaScript มันทำเพื่ออะไรและมันมีประโยชน์อะไร เราลองมาดูกันก่อนว่าจริงๆ ปัญหามันคืออะไรครับ เริ่มเลยตามตัวอย่างด้านล่าง

DemoNameSpace

โดยตัวอย่างไฟล์จะประกอบไปด้วย HTML และ ไฟล์ JS ตามรูป

โดยที่ไฟล์ index.html refer ไฟล์ JavaScript สองไฟล์ตาม Code ด้านล่าง

JsService1.js

 var urlService= 'CallService1';
  
 function GetData1()
 {    
 
 alert(urlService);

 }

JsService2.js

 
 var urlService= 'CallService2';
 
 function GetData2()
 {

 alert(urlService);

 }

และสุดท้ายไฟล์ Index.html

<!DOCTYPE html>
<html>
<head>
<title>JavaScriptThai</title>
  <script src="JsService1.js"></script> 
  <script src="JsService2.js"></script> 
  
  <script>
  GetData1();  //CallService2
  </script>
</head>
<body>

<h1>This is a Heading</h1>
<p>This is a paragraph.</p>

</body>
</html>

จาก Code ด้านบนเราเรียกใช้ Method GetData1()  ของ JsService1.js ตัวที่เรา Refer ไว้เป็นตัวแรก

AlertOfNameSpace

แต่ผลลัพธ์มันไม่ถูกต้องเพราะกลายเป็นว่ามันดันนำค่าของ urlService ของ JsService2.js มาแสดงซึ่งไม่ถูกต้อง ซึ่งสาเหตุนั้นเกิดจากการ ประกาศตัวแปร urlService เป็น Global ของสอง Script (อันนี้ต้องระวังครับเพราะเป็นข้อเสียลำดับต้นๆ ของ JavaScript เลย) โดยตัวที่ถูกประกาศล่าสุดจะเขียนทับตัวที่ประกาศก่อนหน้า (ตามตัวอย่างด้านบน)

 

ข้อแนะนำอย่าพยายามอย่าประกาศตัวแปรเป็นแบบ Global ใน JavaScript (จะลดได้ทั้งข้อผิดพลาดและ เพิ่ม performance อีกด้วยนะครับ)

 

เอาละเรามาดูวิธีแก้กัน ทางแก้มีหลายทางแก้เช่น ก็เปลี่ยนชื่อตัวแปรให้เป็นชื่ออื่นก็จบ อันนี้มันก็ถูกแต่มันก็ยังไม่ถูกต้องตาม Concept ด้านบนที่ผมทำตัวหนาๆ หากเป็น project ใหญ่ที่มันซับซ้อนเราจะเปลี่ยนชื่อมันหมดคงไม่ไหวคงเป็นงานที่น่ากลัวมากกกกกก ^_^

เอาวิธีนี้ดีกว่าคือการกำหนด NameSpace หลายคนคงงง ว่า ภาษานี้มี NameSpace ด้วยเหรอตอนแรกผมก็งงเพราะแต่ก่อนต้องยอมรับเลยว่าใช้งาน JavaScript แค่ Validate เปลี่ยน stylesheet และทำ Effect ทำ Menu เท่านั้นจริงๆๆ   แต่พอมายุคหลังๆ web สมัยใหม่ล้วนแต่ใช้พลังของ JAvaScript ทั้งสิ้น  เอ้ามาเข้าเรื่องกันดีกว่าการกำหนด NameSpace มีหลายรูปแบบมีทั้งที่เป็นแบบ

Static และ Dynamic สองแบบนี้ก็ตามชื่อเลยครับ เราสามารถเพิ่ม Method และแก้ไขได้แบบ Dynamic เท่านั้นถ้าแบบ Static กำหนดแล้วกำหนดเลยเพิ่มไม่ได้มีหัวข้อย่อยดังนี้

Static Namespacing
1. By Direct Assignment
2. Using Object Literal Notation
3. The Module Pattern

Dynamic Namespacing
4. Supply a Namespace Argument
5. Use this as a Namespace Proxy

แต่ผมข้อเลือกใช้วิธีที่ 5. Use this as a Namespace Proxy นะครับมันเป็นความชอบส่วนตัวครับส่วนตัวอื่นๆ เพื่อนๆ ลองไปศึกษาเพิ่มเติมเอานะครับ อะลองมาดู Script ที่เราแก้ใหม่กัน

JsService1.js

 
var JsService1 = {};
(function() {
    var urlService= 'CallService1';
 
    this.GetData = function() {
    alert(urlService);
    };
   
}).apply(JsService1);    

JsService1.js

 
var JsService2 = {};
(function() {
    var urlService= 'CallService2';
 
    this.GetData = function() {
      alert(urlService);
    };
 
}).apply(JsService2);    

และสุดท้ายไฟล์ Index.html

<!DOCTYPE html>
<html>
<head>
<title>JavaScriptThai</title>
  <script src="JsService1.js"></script> 
  <script src="JsService2.js"></script> 
  
  <script>
  JsService1.GetData();  //CallService1   
  JsService2.GetData();  //CallService2 ชื่อ Method ซ้ำกันก็ไม่ใช่ปัญหา
  
  JsService1=null;       //สามารถคืน Memory เพื่อช่วยลด memory leak ได้ง่าย
  JsService2=null;       //สามารถคืน Memory เพื่อช่วยลด memory leak ได้ง่าย
 
  </script>
</head>
<body>

<h1>This is a Heading</h1>
<p>This is a paragraph.</p>

</body>
</html>

แก้แล้วดูดีกว่าแบบแรกว่าไหมครับผม

Demo

หวังว่าคงมีประโยชน์บ้างนะครับ

Leave a Reply