检查JavaScript中深层嵌套对象属性是否存在的最简单方法是什么?

时间:2011-08-03 13:31:51

标签: javascript properties

我必须检查深层嵌套的对象属性,例如 YAHOO.Foo.Bar.xyz

我目前使用的代码是

if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
    // operate on YAHOO.Foo.Bar.xyz
}

这很有效,但看起来很笨拙。

有没有更好的方法来检查这种深层嵌套的属性?

7 个答案:

答案 0 :(得分:18)

如果你希望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
}

答案 1 :(得分:7)

var _ = {};

var x = ((YAHOO.Foo || _).Bar || _).xyz;

答案 2 :(得分:6)

考虑这个效用函数:

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/

答案 3 :(得分:3)

如果你需要检查路径的正确性,而不是“YAHOO.Foo.Bar”对象上“xyz”成员的存在,那么在try catch中包装调用可能是最容易的: / p>

var xyz;
try {
    xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
    // fail;
};

或者,你可以做一些字符串 - 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!
};

答案 4 :(得分:1)

这个问题通过coffeescript(编译为javascript)得到了很好的解决:

if YAHOO.Foo?.Bar?.xyz
  // operate on YAHOO.Foo.Bar.xyz

答案 5 :(得分:0)

使用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
}

答案 6 :(得分:0)

我实际上投票决定将此问题作为javascript convert dotnotation string into objects的副本关闭。

但是,我想这是一个不同的主题,但如果你不想一直try-catch,那么答案可能仍然有用。