我们做个项目想作为一个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不能被使用
更多详细内容见《犀牛书》第十章