由于我们的名字空间是一个对象, 拥有对象应该有的层级关系, 所以在检测名字空间的可用性时, 需要基于这样的层级关系去判断和注册, 这在注册一个子名字空间(sub-namespace)时尤为重要。 比如我们新注册了一个名字空间为Hongru, 然后我们需要再注册一个名字空间为Hongru. me, 亦即我们的本意就是me这个namespace是Hongru的sub-namespace, 他们应该拥有父子的关系。 所以, 在注册namespace的时分需要通过‘. ’来split, 并且停止逐一对应的判断。 所以, 注册一个名字空间的代码大概如下:
// create namespace -- return a top namespace
Module. createNamespace = function (name, version) {
if (!name) throw new Error('name required');
if (name. charAt(0) == '. ' || name. charAt(name. length-1) == '. ' || name. indexOf('. . ') != -1) throw new Error('illegal name');
var parts = name. split('. ');
var container = Module. globalNamespace;
for (var i=0; iparts. length; i++) {
var part = parts;
if (!container[part]) container[part] = {};
container = container[part];
}
var namespace = container;
if (namespace. NAME) throw new Error('module "'+name+'" is already defined');
namespace. NAME = name;
if (version) namespace. VERSION = version;
--版本和重名检测
// check name is defined or not
Module. isDefined = function (name) {
return name in Module. modules;
};
// check version
Module. require = function (name, version) {
if (!(name in Module. modules)) throw new Error('Module '+name+' is not defined');
if (!version) return;
var n = Module. modules[name];
if (!n. VERSION || n. VERSION version) throw new Error('version '+version+' or greater is required');
};
由于我们要的是一个通用的名字空间注册和管理的tool, 所以在做标记导入或导出的时分需要思索到可配置性, 不能一股脑全部导入或导出。 所以就有了我们看到的Module模板中的EXPORT和EXPORT_OK两个Array作为存贮我们允许导出的属性或办法的标记队列。 其中EXPORT为public的标记队列, EXPORT_OK为我们可以自定义的标记队列, 如果你觉得不要分这么清楚, 也可以只用一个标记队列, 用来寄存你允许导出的标记属性或办法。
有了标记队列, 我们做的导出操作就只针对EXPORT和EXPORT_OK两个标记队列中的标记。
// import module
Module. importSymbols = function (from) {
if (typeof form == 'string') from = Module. modules[from];
var to = Module. globalNamespace; //dafault
var symbols = [];
var firstsymbol = 1;
if (arguments. length1 typeof arguments[1] == 'object' arguments[1] != null) {
to = arguments[1];
firstsymbol = 2;
}
for (var a=firstsymbol; aarguments. length; a++) {
symbols. push(arguments[a]);
}
if (symbols. length == 0) {
//default export list
if (from. EXPORT) {
for (var i=0; ifrom. EXPORT. length; i++) {
var s = from. EXPORT;
to[s] = from[s];
}
return;
} else if (!from. EXPORT_OK) {
// EXPORT array EXPORT_OK array both undefined
for (var s in from) {
to[s] = from[s];
return;
}
}
}
if (symbols. length 0) {
var allowed;
if (from. EXPORT || form. EXPORT_OK) {
allowed = {};
if (from. EXPORT) {
for (var i=0; iform. EXPORT. length; i++) {
allowed[from. EXPORT] = true;
}
}
if (from. EXPORT_OK) {
for (var i=0; iform. EXPORT_OK. length; i++) {
allowed[form. EXPORT_OK] = true;
}
}
}
}
//import the symbols
for (var i=0; isymbols. length; i++) {
var s = symbols;
if (!(s in from)) throw new Error('symbol '+s+' is not defined');
if (!!allowed !(s in allowed)) throw new Error(s+' is not public, cannot be imported');
to[s] = form[s];
}
}