我必须检查深层嵌套的对象属性,例如YAHOO.Foo.Bar.xyz。
我目前使用的代码是
if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
}
这有效,但看起来很笨拙。
有没有更好的方法来检查这种深度嵌套的属性?
我必须检查深层嵌套的对象属性,例如YAHOO.Foo.Bar.xyz。
我目前使用的代码是
if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
}
这有效,但看起来很笨拙。
有没有更好的方法来检查这种深度嵌套的属性?
如果您希望YAHOO.Foo.Bar
成为一个有效的对象,但又想让您的代码防弹以防万一,那么在它周围放置一个 try catch 并让一个错误处理程序捕获任何丢失的段可能是最干净的。然后,您可以只使用一个if
条件而不是四个条件来检测终端属性是否存在,如果中间对象不存在,则可以使用一个捕获处理程序来捕获事物:
try {
if (YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// handle error here
}
或者,根据您的代码的工作方式,它甚至可能是这样的:
try {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}
在处理应该具有特定格式的外部输入时,我特别使用这些,但无效输入是我想要捕获和处理自己而不是让异常向上传播的可能性。
通常,一些 javascript 开发人员未充分利用 try/catch。我发现有时我可以用一个更大的功能块周围的单个 try/catch 替换 5-10 个检查输入的 if 语句,同时使代码更简单,更易读。显然,什么时候合适取决于特定的代码,但这绝对值得考虑。
仅供参考,如果通常的操作是不使用 try/catch 抛出异常,那么它也可能比一堆 if 语句快得多。
如果您不想使用异常处理程序,您可以创建一个函数来为您测试任意路径:
function checkPath(base, path) {
var current = base;
var components = path.split(".");
for (var i = 0; i < components.length; i++) {
if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
return false;
}
current = current[components[i]];
}
return true;
}
用法示例:
var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
// a.b.c.d exists and can be safely accessed
}
var _ = {};
var x = ((YAHOO.Foo || _).Bar || _).xyz;
考虑这个效用函数:
function defined(ref, strNames) {
var name;
var arrNames = strNames.split('.');
while (name = arrNames.shift()) {
if (!ref.hasOwnProperty(name)) return false;
ref = ref[name];
}
return true;
}
用法:
if (defined(YAHOO, 'Foo.Bar.xyz')) {
// operate on YAHOO.Foo.Bar.xyz
}
现场演示: http : //jsfiddle.net/DWefK/5/
如果您需要检查路径的正确性,而不是“YAHOO.Foo.Bar”对象上“xyz”成员的存在,那么将调用包装在 try catch 中可能是最简单的:
var xyz;
try {
xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
// fail;
};
或者,您可以执行一些 string-kong-fu-magic TM:
function checkExists (key, obj) {
obj = obj || window;
key = key.split(".");
if (typeof obj !== "object") {
return false;
}
while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ;
return (!key.length && typeof obj !== "undefined");
}
使用方法如下:
if (checkExists("YAHOO.Foo.Bar.xyz")) {
// Woo!
};
这个问题被 coffeescript(它编译成 javascript)很好地解决了:
if YAHOO.Foo?.Bar?.xyz
// operate on YAHOO.Foo.Bar.xyz