1.首先爲什麼要用js命名空間
在我們的項目中,如果多個人爲同一個頁面寫js的話,命名衝突就有可能發生,如果所有的函數都是全局的話,如下:
a.js中
function com()
{
.....
}
b.js中
function com()
{
........
}
且一個頁面同時引用了這兩個js文件,這樣我們調用的時候會出問題,可能老是調用到第一個文件裏面的函數了,我之前在做一個項目的時候就碰到了這個問題,我自己b.js文件中ajax的響應函數的名字和a.js文件中的ajax響應函數名字一樣,結果,ajax響應數據每次到一個a.js中去了,而兩個響應函數要做的功能不一樣,所以出問題了,後來我們是把b.js的ajax的響應函數的名字重命名了,後來就沒有衝突了,(當時我不知道用命令空間的辦法,所以採用這種方法)
其實,如果我弄一個命名空間,這樣a.js裏面的函數在a空間中,b.js裏面的函數在b命令空間中。
這樣我們調用的時候就可以如下調用:
a.com();
b.com();
2.js如何製造命名空間
我們知道很多語言,天生支持命名空間,比如c++,java,等等,但是我們的javascript並沒有在其語法中有規定專門爲命名空間的提供什麼語法,但是如果我們熟悉js的對象字面量的表示法之後,我們就可以徹底的理解js命名空間的玩法了。(其實就是利用js對象字面量這個語法來實現js的命名空間的)
下面我們來介紹一下s命名空間的玩法,還是接着上面的上面提出的這個問題,要想實現如下調用:
a.com();
b.com();
可以用如下方法:
var a={
com: function(){
..........
}
}
var b={
com: function(){
}
}
上面都是採用對象字面量的方法,定義了兩個對象a和對象b是全局的,且兩個對象裏面都有一個com方法,沒有變量,(我們知道js裏面的對象可以擁有屬性和方法),可以看得到我們已經實現js的命令空間了。
例如:登錄界面有一個login.js文件,他的命名空間爲:
var BP={
login:{
//其餘關於這個登錄頁面的函數和全局變量寫在這個裏面,即在這個命名空間裏面
}
}
這個表示全局對象BP裏面有一個login對象,然後關於對登錄界面的操作都在的屬性和方法都要放在login對象裏面,就是關於這個頁面的操作在命名空間BP.login裏面。BP便是項目名字,loging表示本js的功能
很多人可能不習慣這種方式,比較習慣比如BP.login這種方式的來註冊一個命令空間 nameSpace.Register("BP.login")(比較符合其他語言的命令空間); 我們只需要在Resister這個函數裏面動態的創建出BP對象和BP的子對象login。
動態創建對象我們可以通過 兩種方法:1.window 對象實現 2.eval實現。
我們只介紹通過註冊window方法
我們知道定義一個對象可以這樣,window['BP']={}; window.BP['login']={};表示window對象有一個子對象BP,BP有一個子對象login。
下面就是採用這種方法來動態的拆分字符串,然後用上面這種方法動態創建對象的
var nameSpace = nameSpace || {};
(function () {
var global = window;
/**
*
* @param {} nsStr
* @return {}
*/
nameSpace.ns = function (nsStr) {
var parts = nsStr.split("."),
root = global,
max,
i;
for (i = 0, max = parts.length ; i < max ; i++) {
//如果不存在,就創建一個屬性
if (typeof root[parts[i]] === "undefined") {
root[parts[i]] = {};
}
root = root[parts[i]];
}
return root;
};
})();
逐一解釋一下
a.表示nameSpace定義成一個對象
var nameSpace = nameSpace || {};
b.//匿名函數
(function(){
//code,運行的代碼
})();
注意:()在JavaScript中有兩種含義:一是運算符;二是分隔符。
上面匿名函數需要說明兩點:
①紅色括號裏是一個匿名函數,紅色括號代表分割,表示裏面的函數是一個部分;
②綠色括號表示一個運算符,表示紅色括號裏面的函數要運行;相當於定義完一個匿名函數後就讓它直接運行。
3.使用命名空間
在我們登錄的界面的login.js文件中,我們一般希望我們的每一個js文件裏面的代碼都放在自己的命名空間裏面,這樣多個js文件之間就不會有命名衝突了
login.js文件內容如下:
nameSpace.ns("BP.login"); //註冊命令空間
BP.login={
min_height:660,//頁面最小高度
min_widht:1024,//頁面最小寬度
isIE:false,
init:function(){
this.isIE=$.browser.msie;
this.regEvent();
this.initPage();
BP.page.i18nInit();//國際化加載
}
........
.......
}
使用命名空間裏面的函數:
<html>
<head>
<meta name="others" content="login_page">
<script type="text/javascript">
$(document).ready(function(){
BP.login.init();
});
</script>
</head>
<body>
</body>
</html>
utils.js文件內容如下:
nameSpace.ns("BP.utils");
BP.utils = {
time:3000,
timeOut:null,
interValForFake:null,
isProgressBarShow:false,
timeOutReturn:'',
alert:function(content){
var dom=$("#alert_tip");
$(".alert_tip_content",dom).text(content);
if(dom.hasClass("alert_tip_system_config_bg")){//系統設置中
var tbW=$("#tb").width();
var left=tbW/2 -dom.width()/2 +180;
$("#alert_tip").css({"left":left,"top":38});
}else{
var bw=$("body").width();
var left=bw/2 -dom.width()/2;
$("#alert_tip").css("left",left);
}
dom.show();
this.timeOutReturn = setTimeout(function(){
dom.fadeOut(2000);
},2000);
},
.............................
}
總之後面就不再列舉了,反正每一個js文件都有一個自己的命令空間,然後調用的時候帶命名空間名字就可以了!