Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Tránh namespace pollution trong JavaScript

JS không có namespace gốc — mọi biến/function toàn cục cùng chung window (browser) hoặc global (Node). Nạp nhiều file JS dễ gây name collision (trùng tên).

Vấn đề: Name Collision

// TeamA1.js
function Student(fname, lname) { this.fname = fname; this.lname = lname; }

// TeamA2.js (nạp sau)
function Student(fname, mname, lname) { 
  this.fname = fname; this.mname = mname; this.lname = lname; 
}

// HTML nạp cả hai
new Student('Raj', 'Prasad'); // Gọi TeamA2.Student → mname = undefined
// Output: "Raj undefined Prasad" — sai logic!

Giải pháp: Namespace Pattern với Object

Dùng object làm container — "namespace" thủ công.

Pattern cơ bản

var MyApp = MyApp || {}; // Nếu đã có thì dùng, chưa có thì tạo mới

Nested Namespace

var MyApp = MyApp || {};
MyApp.TeamA1 = MyApp.TeamA1 || {};
MyApp.TeamA2 = MyApp.TeamA2 || {};

Triển khai thực tế

TeamA1.js

var Tutorix = Tutorix || {};
Tutorix.TeamA1 = Tutorix.TeamA1 || {};
Tutorix.TeamA1.Student = function(fname, lname) {
  this.fname = fname;
  this.lname = lname;
  this.getFullName = function() {
    return this.fname + ' ' + this.lname;
  };
  return this;
};

TeamA2.js

var Tutorix = Tutorix || {};
Tutorix.TeamA2 = Tutorix.TeamA2 || {};
Tutorix.TeamA2.Student = function(fname, mname, lname) {
  this.fname = fname;
  this.mname = mname;
  this.lname = lname;
  this.getFullName = function() {
    return this.fname + ' ' + this.mname + ' ' + this.lname;
  };
  return this;
};

HTML sử dụng

<script src="TeamA1.js"></script>
<script src="TeamA2.js"></script>
<script>
  document.write(Tutorix.TeamA1.Student('Rajendra', 'Prasad').getFullName()); // Rajendra Prasad
  document.write('<br>');
  document.write(Tutorix.TeamA2.Student('Babu', 'Rajendra', 'Prasad').getFullName()); // Babu Rajendra Prasad
</script>

Kết quả

Rajendra Prasad
Babu Rajendra Prasad

Các pattern nâng cao

IIFE (Immediately Invoked Function Expression) — Private scope

var MyModule = (function() {
  let privateVar = 'secret';
  function privateFn() { ... }
  return {
    publicMethod: function() { ... }
  };
})();

ES6 Modules (Khuyên dùng cho project hiện đại)

// math.js
export const PI = 3.14;
export function add(a, b) { return a + b; }

// main.js
import { add, PI } from './math.js';

Tóm tắt

CáchƯu điểmNhược điểmPhù hợp
Global object namespaceĐơn giản, chạy mọi nơiVẫn global, có thể ghi đèProject nhỏ, legacy
IIFE Module PatternPrivate scope, encapsulationHand-crafted, không tree-shakeLibrary, plugin
ES6 ModulesChuẩn, static analysis, tree-shaking, scopedCần bundler/server hỗ trợProject hiện đại