【问题标题】:Checking existence of nested property in an object javascript检查对象javascript中嵌套属性的存在
【发布时间】:2016-08-29 10:05:12
【问题描述】:

我已经查看了此类问题的一些答案,但是,我想以不同的方式提出我的问题。

假设我们有一个类似 "level1.level2.level3. ..." 的字符串,它表示一个名为 Obj 的对象中的嵌套属性。

关键是我们可能不知道这个字符串中有多少嵌套属性。例如,它可能是“level1.level2”或“level1.level2.level3.level4”。

现在,我想要一个将 Obj 和属性字符串作为输入的函数,只需告诉我们对象中是否存在这样的嵌套属性(让我们说 true 或 false 为输出)。


更新: 感谢@Silvinus,我找到了稍作修改的解决方案:

        private checkNestedProperty(obj, props) {
        var splitted = props.split('.');
        var temp = obj;
        for (var index in splitted) {
            if (temp[splitted[index]] === 'undefined' || !temp[splitted[index]]) return false;
            temp = temp[splitted[index]];
        }
        return true;
    }

【问题讨论】:

  • @Pedram,您想获得有关每个属性存在的“报告”还是仅针对大多数(最后)嵌套的属性?
  • @RomanPerekhrest 事实上,最多(最后)一个。但是,很明显,如果这些属性中的每一个都不存在,那么最后一个也不存在:)
  • 我想知道为什么我的问题应该被否决!

标签: javascript object properties nested


【解决方案1】:

您可以使用此功能探索您的 Obj:

var fn = function(obj, props) {
        var splited = props.split('.');
        var temp = obj;
        for(var index in splited) {
            if(typeof temp[splited[index]] === 'undefined') return false;
            temp = temp[splited[index]]
        }
           return true
        }

var result = fn({ }, "toto.tata");
console.log(result); // false

var result = fn({ toto: { tata: 17 } }, "toto.tata");
console.log(result); // true

var result = fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata");
console.log(result); // false

此函数允许探索 Obj 的嵌套属性,该属性取决于传入参数的 props

【讨论】:

  • 此答案在fn({a:false}, 'a') 的情况下失败。次要的一点,但这里不需要变量temp
  • 另外,不应该是temp = temp[splited[index]];吗?因此,测试用例fn({a: {b: { c: 1 }}}, 'a.b.c') 会导致运行时错误“无法读取未定义的属性'c'”。
  • 对于第一条评论,...我同意。我写这段代码太快了。我对其进行了编辑并通过 if(typeof temp[splited[index]] === 'undefined') return false; 更改了我的测试。第二,对不起,这是一个错误。 temp = obj[splited[index]] 必须替换为 temp = temp[splited[index]]
  • @Silvinus 谢谢,我已经修改了你的答案(小错误)并将正确的功能放入我的更新中。
【解决方案2】:

您可以使用它的Array#every()thisArg,通过迭代键并检查它是否在给定对象中。

var fn = function (o, props) {
    return props.split('.').every(k => k in o && (o = o[k]));
}

console.log(fn({}, "toto.tata"));                                   // false
console.log(fn({ toto: { tata: 17 } }, "toto.tata"));               // true
console.log(fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata")); // false

【讨论】:

    【解决方案3】:

    This answer 为您的问题提供了基本答案。但需要对其进行调整以处理未定义的情况:

    function isDefined(obj, path) {
      function index(obj, i) { 
        return obj && typeof obj === 'object' ? obj[i] : undefined; 
      }
    
      return path.split(".").reduce(index, obj) !== undefined;
    }
    

    【讨论】:

    • 为什么要投反对票?投票者,一些解释怎么样?或者,也许,你只是在没有参数的情况下点击?
    【解决方案4】:

    根据@Silvinus 给出的解决方案,如果您处理嵌套对象内的数组(这在数据库查询的结果中通常是这种情况),这里是一个解决方案:

    checkNested = function(obj, props) {
        var splited = props.split('.');
        var temp = obj;
        for(var index in splited) {
          var regExp = /\[([^)]+)\]/;
          var matches = regExp.exec(splited[index])
          if(matches) {
            splited[index] = splited[index].replace(matches[0], '');
          }
          if(matches) {
            if(matches && typeof temp[splited[index]][matches[1]] === 'undefined') return false;
                temp = temp[splited[index]][matches[1]];
          }
          else {
                if(!matches && typeof temp[splited[index]] === 'undefined') return false;
                    temp = temp[splited[index]]
          }
        }
        return true
    }
    
    obj = {ok: {ao: [{},{ok: { aa: ''}}]}}
    
    console.log(checkNested(obj, 'ok.ao[1].ok.aa')) // ==> true
    console.log(checkNested(obj, 'ok.ao[0].ok.aa')) // ==> false
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多