现在我有一个跟随长链名称空间的模块,例如:
TOP.middle.realModuleName = function () { /*...*/ }
我需要在页面上使用此模块,我不确定此页面是否包含名称空间Top.middle。所以我必须做类似的事情:
if (typeof TOP !== 'undefined' && TOP.middle && TOP.middle.realdModuleName) {
new TOP.middle.realModuleName();
}
我认为if
语句看起来很冗长且冗长。任何人都有关于如何为这种情况编写更好的参数检查模式的建议吗?
答案 0 :(得分:7)
尝试这个简单的辅助函数:
function exists(namespace) {
var tokens = namespace.split('.');
return tokens.reduce(function(prev, curr) {
return (typeof prev == "undefined") ? prev : prev[curr];
}, window);
}
它需要String
作为输入,如果存在则返回该对象。您可以像这样使用它:
var module = exists("TOP.middle.realModuleName");
例如:
exists("noexist"); // returns undefined
exists("window"); // returns DOMWindow
exists("window.innerHeight"); // returns Number
exists("window.innerHeight.toString"); // returns Function
exists("window.innerHeight.noexist"); // returns undefined
它也适用于评估为false的表达式:
testNum = 0;
testBool = false;
testNull = null;
exists("testNum"); // returns 0
exists("testBool"); // returns false
exists("testNull"); // returns null
答案 1 :(得分:6)
只是将其封装在TRY / CATCH中?
try {
return new TOP.middle.blablabla();
}
catch(err) {
// oh no!
}
return null;
答案 2 :(得分:2)
我会尝试类似这样的东西,但如果它收到一些时髦的输入则很容易出错:
if(check("TOP.middle.realModuleName")) {
//exists
}
//namespace checking function
function check(ns) {
var pieces = ns.split('.'),
current = window;
for(i in pieces) {
if(!(current = current[pieces[i]])) {
return false;
}
}
return true;
}
答案 3 :(得分:2)
您可以使用try / catch查找“not_defined
”:
try {
TOP.middle.realModuleName = function () { /*...*/ };
} catch(e) {
if ( e.type == 'not_defined' ) {
// exception
}
else {
// throw other errors
throw e;
}
}
答案 4 :(得分:0)
你可以用这种方式完成整个事情:
TOP && TOP.middle && TOP.middle.realdModuleName && new TOP.middle.realdModuleName;
请注意,您的功能将立即运行。如果要存储该函数以供以后重用,只需指定它(var module =
)。如果未定义模块功能,则设置/丢弃undefined
。
答案 5 :(得分:0)
我使用一个解析命名空间的函数,如果它不存在则创建它。这是功能:
framework.namespace = function(baseName){
var ns = baseName.split('.');
var o = window;
for (var i=0, l=ns.length; i < l; i++){
o = o[ns[i]] = o[ns[i]] || {};
}
return o;
};
然后,在我需要使用命名空间之前,我这样做:
framework.namespace("TOP.middle.realModuleName");
TOP.middle.realModuleName = function(){...};
答案 6 :(得分:0)
我的学习方式(同样适用于名称空间的创建):
// Check if the com namespace does not exist:
if (!com) {
var com = {};
}
// Check if your namespace does not exist:
if (!com.myNamespace) {
var com.myNamespace = {};
}
根据我正在阅读的书,com
名称空间是商业产品的容器(因此,我的意思是网站,图书馆等)。
名称空间最初是创建来容纳域的。但是,今天您会在库,数据库甚至框架中找到com.*
!
它目前由VeriSign运营,并且已经存在 33年!
首先,我们需要确保 main 名称空间存在。如果com
不存在,我们将进行检查:
if (!com) {
var com = {};
}
com
是最常用的名称空间。但是,我们可以检查任何名称空间。
我们可以跳过这部分,但是真的使所有功能混在一起很烦人。
如果com
不存在,则创建它。
var com = {};
最后,我们需要检查myNamespace
是否存在。我们将对com
使用相同的方法,但是这次,我们将在com.
之前添加myNamespace
。
if (!com.myNamespace) {
var com.myNamespace = {};
}
之所以在名称空间声明之前添加com.
是因为com
名称空间是在第二层创建的,而myNamespace是在第三层进行的。 / p>
我建议您为项目添加第四级名称空间。
这样可以确保:
您的项目具有它的拥有名称空间(如果使用了myNamespace)。
您的项目不会与其他项目(例如com.projectA.other和 com.projectA.yourProject )混合在一起。
您的函数不会混淆(例如,您有一个名为write的函数)。
您快到了!这是我的看法:
if (!TOP) {
// Reinitialize your TOP Namespace here:
var TOP = {};
}
if (!TOP.middle) {
// Reinitialize your MIDDLE Namespace here:
var TOP.middle = {};
}
if (typeof TOP.middle.realModuleName == "function") {
new TOP.middle.realModuleName ();
}
else {
// Redefine your function here (you never know ;) )
}