在JavaScript中,是否有更简单的方法来检查属性的属性是否存在?

时间:2011-10-03 15:01:18

标签: javascript

是否有一种简单的方法可以本地确定JavaScript中对象中是否存在深层属性?例如,我需要访问这样的属性:

var myVal = appData.foo.bar.setting;

但是有可能还没有定义foo,foo.bar或foo.bar.setting。在Groovy中,我们可以这样做:

def myVal = appData?.foo?.bar?.setting

有没有类似的方法在JavaScript中执行此操作,而无需编写自定义函数或嵌套if语句?我发现this answer很有用,但我希望有更优雅,更少自定义的方式。

7 个答案:

答案 0 :(得分:16)

我觉得这很方便:

var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;

如果存在属性,则将尝试序列的下一部分。

&&之前的表达式求值为false时,不会检查表达式的下一部分。如果未定义myVal.appData.foo.bar.settings中的任何一个,则myVal的值undefined(将评估为false

答案 1 :(得分:5)

抱歉,这不太好:

var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;

另一种选择:

try {
    var myVal = appData.foo.bar.setting;
} catch (e) {
    var myVal = undefined;
}

。 operator不是真正用于访问这样的对象。可能使用函数是个好主意。

答案 2 :(得分:3)

我发现其他方法有点巨大。那么,以下方法的主要缺点是什么:

// Pass the path as a string, parse it, and try to traverse the chain.
Object.prototype.pathExists = function(path) {
    var members = path.split(".");
    var currentMember = this;

    for (var i = 0; i < members.length; i++) {
        // Here we need to take special care of possible method 
        // calls and arrays, but I am too lazy to write it down.
        if (currentMember.hasOwnProperty(members[i])) {
            currentMember = currentMember[members[i]];   
        } else {
            return false;
        }
    }
    return true;
}

基本上,我们在对象上定义一个方法(不一定),该方法获取嵌套对象的路径并返回存在确认,如appData.pathExists("foo.bar.setting");

编辑: 检查object[prop] == undefined在语义上不正确,因为即使属性已定义,它也将返回false,尽管其值为undefined;这就是我使用hasOwnProperty来检查属性的原因。如果需要获取值,这可能并不重要。

答案 3 :(得分:2)

如果,在:

之后
var myVal = appData.foo && appData.foo.bar && appData.foo.bar.setting;

myVal不是undefined,它会保留appData.foo.bar.setting的值。

答案 4 :(得分:1)

你可以试试这个

var x = {y:{z:{a:'b'}}}
x && x.y && x.y.z && x.y.z.a //returns 'b'

这不如groovy表达式好,但它有效。在遇到第一个未定义变量后,评估停止。

答案 5 :(得分:1)

var product = ...,
    offering = (product||{}).offering,
    merchant = (offering||{}).merchant,
    merchantName = (merchant||{}).name;
if (merchantName)
   displayMerchantName(merchantName);

http://osteele.com/archives/2007/12/cheap-monads

答案 6 :(得分:0)

我刚刚做了这个,所以它可能无法正常工作,我还包括两个测试用例。

function hasPropertyChain(o, properties) {

    var i = 0,
        currentPropertyChain = o;

    if(!o) {
        return false;
    }

    while(currentPropertyChain = currentPropertyChain[properties[i++]]);

    return i - 1 === properties.length;
}


alert(hasPropertyChain({a:{b:{c:'a'}}}, ['a','b','c'])); // true
alert(hasPropertyChain({a:{b:{c:'a'}}}, ['a','b','c', 'd'])); // false