想要获得专家的意见,我宣布一个变量将作为我的应用程序javascript代码的命名空间,但我想检查它尚未定义。
这段代码很简洁,“似乎”可以工作 - 我应该避免这种情况并使用typeof'undef'检查吗?
var MY_NAMESPACE = MY_NAMESPACE || {};
由于
答案 0 :(得分:6)
这是执行此操作的标准方法。请参阅使用此相同检查的YUI Matt Snider's analysis的YAHOO.namespace
function(另请参阅如何轻松创建名称空间)。
Matt的代码,他从YUI改编为window
对象而不是YAHOO
对象的命名空间:
window.object_mes_namespace = function() {
var a = arguments,
o = window,
i = 0,
j = 0,
tok = null,
name = null;
// iterate on the arguments
for (i = 0; i < a.length; i = i + 1) {
tok = a[i].split(".");
// iterate on the object tokens
for (j = 0; j < tok.length; j = j + 1) {
name = tok[j];
o[name] = o[name] || {};
o = o[name];
}
}
return o;
}
请注意o[name] = o[name] || {};
行,与您的示例相似。
答案 1 :(得分:3)
虽然您发布的内容常见,但我个人认为这不是最好的方法。
MY_NAMESPACE
以外的其他几个原因, undefined
可以评估为false - 该变量可以真正定义,但可以是0
或false
或空字符串,您最终可能会替换此值。
MY_NAMESPACE
可以评估为true,除了已经是一个对象之外的几个原因 - 它可能是一个非零数字或true
或一个字符串,这将导致你的脚本无声地失败,因为向基元添加属性将失败而没有错误。
真的,最好的方法取决于你的目标是什么。如果您不想污染现有的变量/命名空间,则应该进行typeof
检查并在已定义变量但不是对象时停止:
if (typeof MY_NAMESPACE == 'undefined') {
// create a new namespace
MY_NAMESPACE = {};
}
if (typeof MY_NAMESPACE == 'object') {
// go ahead
} else {
// MY_NAMESPACE was already defined, but it is not an object
// your script will fail if you continue, so do what you must and stop
}
如果您的脚本必须工作,只需盲目地创建命名空间而不进行任何检查(当然,我不建议您这样做)。
编辑(响应@ jball的评论,我想我只是在这里添加)
如果此命名空间是您正在开发的库的一部分,则必须仔细命名您的命名空间以避免冲突。如果您遇到碰撞,最好只是停止加载您的库而不是将您的库与另一个库混合并获得意外结果。
如果此命名空间仅适用于您自己的应用程序,则选择您正在使用的任何库未使用的名称应该相当简单。
答案 2 :(得分:1)
这已经是首选方式了。
但是你的陈述什么都不做,除非你将MY_NAMESPACE
泄漏到另一个范围,因为MY_NAMESPACE
是MY_NAMESPACE
。
答案 3 :(得分:1)
我喜欢YUI example并将其用于我的所有应用。在你的情况下,无论如何,你都会重新分配MY_NAMESPACE,这不是什么大不了的事,但如果没有必要,我更愿意避免这个任务。
if (typeof myNamespace == "undefined" || !myNamespace) {
var myNamespace = {};
}