我需要检查深度嵌套的对象属性,例如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
条件语句,而不是四个,来检测终端属性是否存在,以及一个catch处理程序来捕获中间对象不存在的情况: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
}
if
语句更有效地使用,特别是当你处理不一定控制并且测试每个操作可能非常昂贵的外部输入时。 - jfriend00var _ = {};
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
}
var xyz;
try {
xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
// fail;
};
另外,您也可以运用一些字符串技巧魔法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!
};
typeof obj !== "object"
测试的意义所在。为什么要这么限制呢? - hugomgtry/catch
会有点繁琐。 - Mattif YAHOO.Foo?.Bar?.xyz
// operate on YAHOO.Foo.Bar.xyz
我实际上投票将该问题关闭为javascript convert dotnotation string into objects的重复。
然而,我猜这是一个不同的话题,但如果你不想一直使用try-catch
,那里的答案仍然可能有帮助。
使用 try catch
。
a={
b:{}
};
//a.b.c.d?true:false; Errors and stops the program.
try{
a.b.c.d;
}
catch(e){
console.log(e);//Log the error
console.log(a.b);//This will run
}
if (YAHOO.Foo.Bar.xyz)
? - Michael Berkowskiif (YAHOO.Foo.Bar.xyz)
,因为如果 Foo 或 Bar 不存在,那么if (YAHOO.Foo.Bar.xyz)
将会抛出异常,因为中间的值未定义。 - jfriend00try...catch
会影响性能 - 当抛出异常时,代码将变慢。jsPerf测试。 - Digital Plane