js-OOP: Tạo namespace và nhóm các class thành các gói trong javascript – Part 2

js-OOP: Tạo namespace và nhóm các class thành các gói trong javascript – Part 2

Trong bài viết trước tôi đã đề xuất một mẫu đơn giản cho phép xây dựng một class trong javascript với hàm khởi tạo, access modifier: public và private. Trong bài viết này, tôi sẽ trình bày cách cài đặt (giả lập) namespace giúp cho việc nhóm các class vào chung một nhóm, tránh việc xung đột về tên (tương tự như trong các ngôn ngữ lập trình khác)

Namespace trong javascript

Trong javascript không có khái niệm namespace đúng nghĩa như các ngôn ngữ lập trình khác. Nhưng ta có thể giả lập nó bằng cách coi một object chính là một namespace, bên trong object đó chứa các hàm khởi tạo và định nghĩa các lớp. Object namespace luôn phải được tạo thể hiện và là duy nhất:
Ví dụ cách tạo một namespace đơn giản:

// định nghĩa namespace vn.eten.tek
vn = {};
vn.eten = {};
vn.eten.tek = {};

// định nghĩa class Sample trong namespace vn.eten.tek
vn.eten.tek.Sample = function(){
	// định nghĩa class theo mẫu của bài trước
}

Kỹ thuật đảm bảo giữ được các namespace con và các lớp trong nó

Với cách viết như trong ví dụ trên, nó sẽ là đúng nếu như ta thực hiện việc cài đặt các namespace và các lớp tại cùng một chỗ. Khi ta cài đặt các lớp ở các vị trí khác nhau, ví dụ như mỗi lớp được viết trên một file js khác nhau, thì có thể dẫn đến việc mất tham chiếu dẫn đến mất định nghĩa class hoặc namespace con.
Ví dụ cho trường hợp bị lỗi trên:

//// file Sample1.js

// định nghĩa namespace vn.eten.tek
vn = {};
vn.eten = {};
vn.eten.tek = {};

// định nghĩa class Sample1 trong namespace vn.eten.tek
vn.eten.tek.Sample1 = function(){
	// định nghĩa class Sample1
}
//// file Sample2.js

// định nghĩa namespace vn.eten.tek
vn = {};
vn.eten = {};
vn.eten.tek = {};

// định nghĩa class Sample2 trong namespace vn.eten.tek
vn.eten.tek.Sample2 = function(){
	// định nghĩa class Sample2
}

Ta import cả 2 file Sample1.js và Sample2.js vào trang HTML:

<script type="text/javascript" src="Sample1.js"></script>
<script type="text/javascript" src="Sample2.js"></script>

Kết quả trong namespace vn.eten.tek chỉ có class Sample2 do object vn đã bị ghi đè giá trị bởi một object khác khi import file Sample2.js

Để đảm bảo không bị ghi đè, ta sử dụng kỹ thuật sau: Sử dụng toán tử ||, với biểu thức x = a || b; (a, b đều là object) thì x = a nếu a khác null trái lại x = b. Dựa vào tính chất trên, ta có thể viết một cách rất ngắn gọn để định nghĩa namespace mà không sợ bị ghi đè object khác vào:

// định nghĩa namespace vn.eten.tek
vn = vn || {};
vn.eten = vn.eten || {};
vn.eten.tek = vn.eten.tek || {};

// định nghĩa class Sample trong namespace vn.eten.tek
vn.eten.tek.Sample = function(){
	// định nghĩa class Sample
}

Như vậy khi các namespace vn, vn.eten, vn.eten.tek đã được định nghĩa ở trước đó thì sẽ vẫn giữ nguyên, trái lại sẽ được gán bằng một object rỗng.

Trên đây tôi đã trình bày cách để cài đặt một namespace một cách khá đơn giản trong javascript. Trong bài tới tôi sẽ trình bày về cách thực hiện cài đặt các thuộc tính và phương thức tĩnh (static property và static method).

Khi trích dẫn bài viết từ tek.eten.vn, xin vui lòng ghi rõ nguồn. Chúng tôi sẽ rất cảm ơn bạn!