如果我有对象的引用:

var test = {};

可能(但不是立即)具有嵌套对象,例如:

{level1: {level2: {level3: "level3"}}};

检查深度嵌套对象中是否存在属性的最佳方法是什么?

警报(测试级别1);生成未定义,但警告(test.level1.level2.level3);失败。

我目前正在做这样的事情:

if(test.level1 && test.level1.level2 && test.level1.level2.level3) {
    alert(test.level1.level2.level3);
}

但我想知道是否有更好的方法。


当前回答

CMS解决方案工作得很好,但使用/语法可能更方便。我建议如下

var checkNested = function(obj, structure) {

  var args = structure.split(".");

  for (var i = 0; i < args.length; i++) {
    if (!obj || !obj.hasOwnProperty(args[i])) {
      return false;
    }
    obj = obj[args[i]];
  }
  return true;
};

您可以简单地使用使用点的对象表示法,而不是提供多个参数

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1.level2.level3'); // true
checkNested(test, 'level1.level2.foo'); // false

其他回答

我以以下方式使用函数。

var a = {};
a.b = {};
a.b.c = {};
a.b.c.d = "abcdabcd";

function isDefined(objectChainString) {
    try {
        var properties = objectChainString.split('.');
        var currentLevel = properties[0];
        if (currentLevel in window) {
            var consolidatedLevel = window[currentLevel];
            for (var i in properties) {
                if (i == 0) {
                    continue;
                } else {
                    consolidatedLevel = consolidatedLevel[properties[i]];
                }
            }
            if (typeof consolidatedLevel != 'undefined') {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } catch (e) {
        return false;
    }
}

// defined
console.log(checkUndefined("a.b.x.d"));
//undefined
console.log(checkUndefined("a.b.c.x"));
console.log(checkUndefined("a.b.x.d"));
console.log(checkUndefined("x.b.c.d"));

这是我从奥利弗·斯蒂尔那里学到的一个模式:

var level3 = (((test || {}).level1 || {}).level2 || {}).level3;
alert( level3 );

事实上,整篇文章讨论了如何在javascript中实现这一点。他决定使用上面的语法(一旦你习惯了,它就不那么难读了)作为成语。

创建全局函数并在整个项目中使用

试试这个

函数isExist(arg){尝试{返回参数();}捕获(e){return false;}}让obj={a:5,b:{c:5}};console.log(isExist(()=>obj.b.c))console.log(isExist(()=>obj.b.foo))console.log(isExist(()=>obj.test.foo))

if条件

if(isExist(()=>obj.test.foo)){
   ....
}

根据之前的评论,这里是另一个无法定义主对象的版本:

// Supposing that our property is at first.second.third.property:
var property = (((typeof first !== 'undefined' ? first : {}).second || {}).third || {}).property;

这有一个小模式,但在某些时候可能会让人不知所措。我建议您一次使用两个或三个嵌套。

if (!(foo.bar || {}).weep) return;
// Return if there isn't a 'foo.bar' or 'foo.bar.weep'.

正如我可能忘记提到的,你也可以进一步扩展。下面的示例显示了对嵌套foo.bar.weep.woop的检查,如果没有可用的,则返回。

if (!((foo.bar || {}).weep || {}).woop) return;
// So, return if there isn't a 'foo.bar', 'foo.bar.weep', or 'foo.bar.weep.woop'.
// More than this would be overwhelming.