js尽管不像其余后端语言那样有命名空间的内置支持,但也能通过相似的效果和闭包来实现命名空间。
先详情六种简单实现的方式,如下:
1.单一全局变量
var myApp = (function(){
function method1() {
//…
},
return {
//…
method1 : method1
};
})();
2.前缀命名空间
var myApp_propertyA = {};
var myApp_propertyB = {};
var myApp_method1 = function() {//…}
3.对象字面量表示法
var myApp = {
/*…*/
models : {},
views : {},
collections : {}
};
myApp.method1 = function() {//..}
4.嵌套命名空间
var myApp = myApp || {};
myApp.models = myApp.models || {};
myApp.models.modelUtil = myApp.models.modelUtil || {};
5.函数自执行(立即调使用表达式)
(function(namespace) {
namespace.propertyA = “you…”;
namespace.method1 = function() {//…}
})(window.myApp = window.myApp || {});
6.命名空间注入
var myApp = myApp || {};
myApp.utils = myApp.utils || {};
(function(){
this.propertyA = “you…”;
this.method1 = function() {//…}
}).apply(myApp.utils);
我们着重地说说第四种,那么第四种可以不可以像其余语言那样也可以优雅的看出是命名空间的意思呢?答案是:有的。这里我写个方法,以飨读者,如下:
var Utils = (function(window,undefined){
/*..其余通使用函数…*/
var namespace = function(){
var a, v, x, o, d, i, j, len1, len2;
a = arguments;
len1 = a.length;
// 支持多参数,如两个参数(a.b.c, d.e)
for(i = 0; i < len1; i++){
d = a[i].split('.'); // 分解成数组,如把a.b.c分解成[a,b,c]
o = window[d[0]] = window[d[0]] || {}; // 保证a是对象,若果全局有就使用全局
,假如没有就新建{}
x = d.slice(1);//取出[b,c]
len2 = x.length;
// 支持嵌套,对b和c
for(j = 0; j < len2; j++){
v = x[j]
o = o[v] = o[v] || {}; // o逐层深入,保证每层都是对象,假如是b,o变为a.b,假如是c,o最后变成a.b.c
}
}
}
return {
/*..其余通使用函数…*/
namespace : namespace
}
})(window);
关于用,例子如下:
Utils.namespace('myApp.models');
myApp.models.Cat = function(config) {
if(typeof config !== 'object'){
throw new Error(“构造参数对象不可以为空”);
return;
}
this.name = config.name;
}
myApp.models.Cat.prototype = {
sayName : function(){
console.log(“hello! my name is “+this.name);
}
}
// 缓存为局部变量便于屡次用
var Cat = myApp.models.Cat;
var c1 = new Cat({
name : 'Ketty'
})
c1.sayName();
文/丁向明
做一个有博客的web前台自媒体人,专注web前台开发,关注使用户体验,加我qq/微信交流:6135833
http://dingxiangming.com