JavaScript中的模組和名字空間是不可區分的內容。
我們定義的每個單獨的函數都是作為全域對象的一個屬性。而JavaScript代碼模組所必須遵循的最重要的規則就是:避免定義全域變數。因為,當定義一個全域變數時,都要被其他模組覆蓋的危險,所以模組化編碼要用如下方式:
var ModuleClass={};
ModuleClass.函數名1=function(){
函數體;//這個函數看起來是一個對象的方法。對,可以利用對象作為一個名字空間。
}
ModuleClass.函數名2=function(){
函數體;
}
使用對象作為一個名字空間,將所有的函數及變數都放在其中。這樣,即使函數或變數重名(即不同對象中有相同的函數名),他們不在一個名字空間中,這樣就不會有被覆蓋的危險了。
JavaScript模組化的第一條規則:一個模組不應該為全域名字空間添加多於一條的標記。解釋:上例中的var ModuleClass = {};其實是在全域名字空間(全域對象)的一個屬性。通俗的講:除了給全域命名空間定義一個模組的命名空間,其他的你一句代碼都不要寫。
將上面的代碼放入一個*.js檔案中,以便模組的複用,並且是檔案名稱與名字空間名要一致。假設我們將上面的代碼放入ModuleClass.js檔案當中(這時,你的名字空間與檔案名稱要一致)。現在又出現了一個新問題:
如果名字衝突怎麼辦?即兩個人同時使用了同一個檔案名稱。大家知道,同一目錄下市不允許有相同的檔案名稱的,所以可以把這兩個檔案放入不同的目錄下面。如util/ModuleClass.js和tools/ModuleClass.js,這時我們檔案中的空間就不能跟以前那樣了,而是如下面所示:
util/ModuleClass.js
var util;
if(!util) util = {};//第頂層網域
util.ModuleClass = {};//第次層網域
util.ModuleClass.函數名1=funciton(){
函數體;
}
util.ModuleClass.函數名2=function(){
函數體;
}
tools/ModuleClass.js代碼:
var tools;
if(!tools)tools={};//頂層網域
tools.ModuleClass={};//次層網域
tools.ModuleClass.函數名1=function(){
函數體;//這個函數看起來是一個對象的方法。對,可以利用對象作為一個名字空間
}
tools.ModuleClass.函數名2=function(){
函數體;
}
這樣就不會出衝突了。當然,有人會問了,要是有人定義的檔案夾名是一樣的,那不照樣衝突?首先,這樣的幾率不大,如果真的有我們可以採用java的命名方式。如下:
命名空間為:com.公司名.項目名.util.空間名;
實際路徑為:com/公司名/項目名/util/空間名.js
現在我們以com.util.ModuleClass命名空間為例來看一段代碼:
var com;
if(!com) com = {};//如果com不存在,則新產生一個
else if(typeof com!="object"){//如果已存在,但不是一個對象,則拋出一個異常
throw new Error("XXXXXXXXXXXXXXXXXXXXXXX");
}
if(!com.util) com.util={};//如果com.util不存在則新產生一個
else if(typeof com.util="object"){//如果com存在,但不是一個對象,則拋出一個異常
throw new Error("XXXXXXXXXXXXXXXXXXXXXXXX");
}
if(!com.util.ModuleClass){//如果com.util.ModuleClass存在,則直接拋出異常
throw new Error("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}
com.util.ModuleClass = {//在com.util.ModuleClass不存在的情況下,我們才能正常使用在此命名空間下定義的代碼
函數1:function(){函數體;}
函數2:function(){函數體;}
};
本文來自:http://han2000lei.javaeye.com/blog/342810
但是文章是本人手動敲上去的,以為我覺得ctrl+c、ctrl+v沒有太大的意義。。