我有基于json的数据结构,对象包含嵌套对象。为了访问特定的数据元素,我一直在将对象属性的引用链接在一起。例如:
var a = b.c.d;
如果未定义b或b.c,则会失败并显示错误。但是,我希望得到一个值,如果它存在,否则只是未定义。在不检查链中的每个值是否存在的情况下,最好的方法是什么?
我想保持这种方法尽可能通用,所以我不必添加大量的辅助方法,如:
var a = b.getD();
要么
var a = helpers.getDFromB(b);
我也想尝试避免try / catch构造,因为这不是错误所以使用try / catch似乎是错误的。这合理吗?
有任何想法吗?
您可以创建一个基于属性名称数组访问元素的通用方法,该属性名称数组被解释为通过属性的路径:
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"]);
标准方法:
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; }
如果您之前已经分配过它。
这可能比第一个选项更快。
这是一个老问题,现在有了es6功能,这个问题可以更容易解决。
const idx = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);
感谢@sharifsbeat 解。
如果您希望动态访问具有不规则数量的属性,在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"));
可能它可能很简单:
let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}}
console.log((a || {}).a2); => undefined
console.log(((a || {}).c1 || {}).d1) => 13
等等。
获取值 path
的 object
。如果解析的值是 undefined
, defaultValue
在它的位置返回。
在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"}}