问题 安全地访问Javascript嵌套对象


我有基于json的数据结构,对象包含嵌套对象。为了访问特定的数据元素,我一直在将对象属性的引用链接在一起。例如:

var a = b.c.d;

如果未定义b或b.c,则会失败并显示错误。但是,我希望得到一个值,如果它存在,否则只是未定义。在不检查链中的每个值是否存在的情况下,最好的方法是什么?

我想保持这种方法尽可能通用,所以我不必添加大量的辅助方法,如:

var a = b.getD();

要么

var a = helpers.getDFromB(b);

我也想尝试避免try / catch构造,因为这不是错误所以使用try / catch似乎是错误的。这合理吗?

有任何想法吗?


10300
2017-08-12 01:30


起源

stackoverflow.com/questions/6491463/... - goat


答案:


您可以创建一个基于属性名称数组访问元素的通用方法,该属性名称数组被解释为通过属性的路径:

function getValue(data, path) {
    var i, len = path.length;
    for (i = 0; typeof data === 'object' && i < len; ++i) {
        data = data[path[i]];
    }
    return data;
}

然后你可以用:

var a = getValue(b, ["c", "d"]);

5
2017-08-12 01:40



鉴于a.b === a ['b']我假设使用字符串来引用对象被认为是JS的最佳实践? - Hubris
@Hubris - 属性名称始终是字符串。点符号被认为是“语法糖”(如果属性名称是保留字或不是有效的JS标识符,则甚至不起作用)。 - Ted Hopp
好的,这就是我的想法。真棒。谢谢 :) - Hubris
@Hubris - 请注意Chris的评论;它链接到一个使用相同想法的答案,但是很有风趣。它允许您传递单个字符串,如“c.d”,然后按照指示的路径为您解析它。 - Ted Hopp


标准方法:

var a = b && b.c && b.c.d && b.c.d.e;

很快但不太优雅(特别是使用较长的属性名称)。

使用函数遍历JavaScipt对象属性既不高效也不优雅。

试试这个:

try { var a = b.c.d.e; } catch(e){}

万一你确定 a 以前没用过或

try { var a = b.c.d.e; } catch(e){ a = undefined; }

如果您之前已经分配过它。

这可能比第一个选项更快。


7
2017-07-02 17:05





这是一个老问题,现在有了es6功能,这个问题可以更容易解决。

const idx = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);

感谢@sharifsbeat


2
2017-10-14 10:25





如果您希望动态访问具有不规则数量的属性,在ES6中您可以轻松地执行以下操作:

function getNestedValue(o,...a){
  var val = o;
  for (var prop of a) val = typeof val === "object" &&
                                   val !== null     &&
                                   val[prop] !== void 0 ? val[prop]
                                                        : undefined;
  return val;
}
var obj = {a:{foo:{bar:null}}};
console.log(getNestedValue(obj,"a","foo","bar"));
console.log(getNestedValue(obj,"a","hop","baz"));


0
2017-11-01 07:25





可能它可能很简单:

let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}}
console.log((a || {}).a2); => undefined
console.log(((a || {}).c1 || {}).d1) => 13

等等。


0
2018-03-26 10:57





获取值 path 的 object。如果解析的值是 undefineddefaultValue 在它的位置返回。

在ES6中,我们可以从中获取嵌套属性 Object 如下 代码段

const myObject = {
    a: {
      b: {
        c: {
          d: 'test'
        }
      }
    },
    c: {
      d: 'Test 2'
    }
  },

  isObject = obj => obj && typeof obj === 'object',

  hasKey = (obj, key) => key in obj;



function nestedObj(obj, property, callback) {
  return property.split('.').reduce((item, key) => {
    if (isObject(item) && hasKey(item, key)) {
      return item[key];
    }
    return typeof callback != undefined ? callback : undefined;
  }, obj);
}

console.log(nestedObj(myObject, 'a.b.c.d')); //return test


console.log(nestedObj(myObject, 'a.b.c.d.e')); //return undefined


console.log(nestedObj(myObject, 'c.d')); //return Test 2


console.log(nestedObj(myObject, 'd.d', false)); //return false


console.log(nestedObj(myObject, 'a.b')); //return {"c": {"d": "test"}}


0