關於javascript模塊和命名空間(Module and namespace)

我們做個項目想作爲一個Module,要讓它能在各個地方運行,就需要避免定義全局變量global variables和全局函數global function. 所以就要給自己的所有的variables和functions變成一個empty object 的屬性或者方法,如例:

// Create an empty object as our namespace
// This single global symbol will hold all of our other symbols
var Module;
if(Module && (typeof Module != "object" || Module.Name))
	throw new Error("Namespace 'Module' already exists");
Module = {};

// Define all variables and functions within the namespace
Module.max = 10;
Module.define = function(){ /* code goes here*/}
Module.provides = function(o, c){ /*code goes here*/}
Module.sayHi = function(){ /* code goes here*/}

這樣需要用的時候我們原來比如寫 sayHi(), 現在這樣寫Module.sayHi();


另外現在更流行的一種是通過閉包作爲私有命名空間和作用域,使用閉包來創建一個私有命名空間,然後將其共有方法導出到一個公有的命名空間中。

如例:

// Create the namespace object. Error checking omitted here brevity
// Instead of using com.davidflanagan.Class
// we can also simply say var Module={} as the example above
// the reason to use com.davidflanagan.Class is just 100% ensure the name is UNIQUE
var com;
if(!com) com = {};
if(!com.davidflanagan) com.davidflanagan = {};			
com.davidflanagan.Class = {};

// Don't stick anything into the namespace directly
// Instead we define and invoke an anonymous function to create a closure
// that serves as our private namespace. This function will export its
// public symbols from the closure into the Module object
// Note that we use an unnamed function so we don't create any other global symbols
(function(){ // Begin anonymous function definition
	// Nested functions create symbols within the closure
	function define(data) {counter+=data; /* more code here*/}
	function provides(o, c) { /* code here*/}
	
	// local variable are symbols within the closure
	// This one will remain private within the closure
	var counter = 0;
	function localMethod(){ return "This is local method"};
	console.log(localMethod()); // This is local method
	
	// This function can refer to the variable with a simple name
	// instead of having to qualify it with a namespace
	function getCounter(){ return counter;}
	
	// Now that we will defined the properties we want in our private closure
	// we can export the public ones to the public namespace
	// and leave the private ones hidden here.
	var ns = com.davidflanagan.Class;
	
	// Define all variables and functions within the namespace
	ns.define = define;
	ns.provides = provides;
	ns.getCounter = getCounter;
})(); // End anonymours function definition and invoke it

com.davidflanagan.Class.define(5);
console.log(com.davidflanagan.Class.getCounter()); // 5
console.log(com.davidflanagan.Class.localMethod()); // ERROR 命名空間中private function未經export不能被使用

更多詳細內容見《犀牛書》第十章


發佈了29 篇原創文章 · 獲贊 2 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章