【问题标题】:Check if object member exists in nested object检查嵌套对象中是否存在对象成员
【发布时间】:2026-02-12 17:50:01
【问题描述】:

有没有比使用___ in object检查对象的每个级别的存在来检查单个成员的存在更简单的方法?

更简洁:如何检查 someObject.member.member.member.value 是否存在?

【问题讨论】:

    标签: javascript object


    【解决方案1】:

    一般情况下,您可以使用if(property in object),但这对于嵌套成员来说仍然很麻烦。

    你可以写一个函数:

    function test(obj, prop) {
        var parts = prop.split('.');
        for(var i = 0, l = parts.length; i < l; i++) {
            var part = parts[i];
            if(obj !== null && typeof obj === "object" && part in obj) {
                obj = obj[part];
            }
            else {
                return false;
            }
        }
        return true;
    }
    
    test(someObject, 'member.member.member.value');
    

    DEMO

    【讨论】:

    • 看起来不错。我喜欢循环方法,但是 typeof obj === "object" 究竟有什么帮助呢? typeof 不也可以为 null 和数组返回对象吗?
    • @JustcallmeDrago: True... 不过对于数组来说并没有那么重要,但对于null 来说会失败。因此,最好也添加对 null 的检查。我添加了测试,因为'value' in &lt;primitive type&gt; 会抛出错误。添加了null 测试。
    • @Felix:我明白了。我真的很喜欢字符串作为参数,而且帕特里克的回答也很简单。他的和你的一样安全吗?有那么快吗?
    • @JustcallmeDrago:他的速度可能更快。但是你会遇到最后一个值的问题。他的代码结果要么是undefined,要么是最后一个属性的值。如果将其设置为undefined,则您无法区分。但是假设你从来没有设置过这样的值,它应该被保存。老实说,我发现它有点难以阅读,如果你想重复使用,你会再次使用循环......但两者都可以工作。
    • 抱歉打断了,但是……这里有人提到“帕特里克的回答”更快。呃……这个答案在哪里? :-?
    【解决方案2】:

    您也可以尝试/捕获 TypeError?

    try {
      console.log(someObject.member.member.member.value);
    } catch(e) {
      if (e instanceof TypeError) {
        console.log("Couldn't access someObject.member.member.member.value");
        console.log(someObject);
      }
    }
    

    【讨论】:

      【解决方案3】:

      这是一种方式:http://jsfiddle.net/9McHq/

      var result = ((((someObject || {}).member || {}).member || {}).member || {}).value;
      
      alert( result );
      

      【讨论】:

      • 不错。当然,这可以很容易地变成递归函数!
      【解决方案4】:
      【解决方案5】:
      if (someObject.member && someObject.member.member &&
          someObject.member.member.member && someObject.member.member.member.value) ...
      

      或类似:

      var val = foo.bar && foo.bar.jim && foo.bar.jim.jam && foo.bar.jim.jam.value;
      

      如果任何特定值恰好是 nullfalse0""(一个空字符串),这将不会“起作用”,但除了最终值可能存在的例外情况外,这似乎不太可能。

      另外,请注意typeof ____ !== "undefined" 不是查看对象是否具有属性的正确测试。相反,您应该使用___ in object,例如if ("member" in someObject)。这是因为您可以将属性设置为显式值undefined,这与使用delete someObject.member 删除它不同。

      【讨论】:

        【解决方案6】:

        类似的东西(警告:前面有未经测试的代码)

        var testProperty = function(obj, proplist) {
           for (var i=0; i < proplist.length; i++) {
              if (obj.hasOwnProperty(proplist[i])) {
                 obj = obj[proplist[i]];
              } else {
                return false;
              }
           }
           return true;
        }
        

        【讨论】:

        • @Felix -- 谢谢,已修复。另外,请参阅 Phrogz 的答案以替代 hasOwnProperty
        • 查看我的回答的评论,如果objnull,你的回答也会失败。
        【解决方案7】:

        定义了一个安全读取函数here on thecodeabode,它允许安全读取嵌套属性 即

        safeRead(foo, 'bar', 'jim', 'jam');
        

        如果任何属性为 null 或未定义,则返回空白字符串 - 用于格式化/字符串插值

        【讨论】:

        • 我真的很喜欢这个解决方案
        【解决方案8】:

        如果你可以使用lodash库,它有一个非常优雅的解决方案,hasIn

        _.hasIn(someObject, 'member.level1.level2.level3');
        

        例如,

        var obj = {'x': 999, 'a': {'b': {'c': 123, 'd': 234}}}
        // => undefined
        
        _.hasIn(obj, 'x')
        // => true
        
        _.hasIn(obj, 'a.b.d')
        // => true
        
        _.hasIn(obj, 'a.b.e')
        // => false
        

        【讨论】: