命名空间(namespace)是一种很常用的管理各种类的方式,javascript的目前版本还没有原生态地实现这个功能,只能去手动模拟一下,代码如下:
var $package=function(ns,clzName,clz){
var defineNamespace=function(root,ns){
ns=ns || "";
ns=ns.replace(/\s/g,"");
if (ns.length == 0) {
return root;
}else {
var nsc = ns.substr(0, 1);
if (nsc != nsc.toLowerCase()) {
throw new Error("命名空间首字母必须小写哦~");
}
if (ns.indexOf(".") == -1) {
typeof(root[ns]) != "object" && (root[ns] = {});
return root[ns];
}
else {
var _ns = ns.split(".")[0];
typeof(root[_ns]) != "object" && (root[_ns] = {});
return defineNamespace(root[_ns], ns.replace(/[^\.]*\./, ""));
}
}
},
c=clzName.substr(0,1);
if(c!=c.toUpperCase()){
throw new Error("类名首字母必须大写哦~");
}
defineNamespace(window,ns)[clzName]=clz;
};
var defineNamespace=function(root,ns){
ns=ns || "";
ns=ns.replace(/\s/g,"");
if (ns.length == 0) {
return root;
}else {
var nsc = ns.substr(0, 1);
if (nsc != nsc.toLowerCase()) {
throw new Error("命名空间首字母必须小写哦~");
}
if (ns.indexOf(".") == -1) {
typeof(root[ns]) != "object" && (root[ns] = {});
return root[ns];
}
else {
var _ns = ns.split(".")[0];
typeof(root[_ns]) != "object" && (root[_ns] = {});
return defineNamespace(root[_ns], ns.replace(/[^\.]*\./, ""));
}
}
},
c=clzName.substr(0,1);
if(c!=c.toUpperCase()){
throw new Error("类名首字母必须大写哦~");
}
defineNamespace(window,ns)[clzName]=clz;
};
现在就可以用package的方式申明了:
$package("common.app.test","Point",function(x,y){
this.x= x || 0;
this.y= y || 0;
});
this.x= x || 0;
this.y= y || 0;
});
这样就可以用namespace+classname的方式来实例化对象了:
var p=new common.app.test.Point(1,2);
alert(p.constructor===common.app.test.Point);
alert(p.x);
alert(p.y);
alert(p.constructor===common.app.test.Point);
alert(p.x);
alert(p.y);
不过目前还没有考虑好怎样才能优雅地解决import namespace的问题,要么在使用类的时候,直接用绝对路径,要么就用个中转的变量引用,如:
var Point=common.app.test.Point;
var p=new Point(1,2);
alert(p.constructor===common.app.test.Point);
alert(p.x);
alert(p.y);
var p=new Point(1,2);
alert(p.constructor===common.app.test.Point);
alert(p.x);
alert(p.y);