如果我有对象的引用:
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);
}
但我想知道是否有更好的方法。
答案很多,但仍然是:为什么不更简单?
获取值的es5版本为:
function value(obj, keys) {
if (obj === undefined) return obj;
if (keys.length === 1 && obj.hasOwnProperty(keys[0])) return obj[keys[0]];
return value(obj[keys.shift()], keys);
}
if (value(test, ['level1', 'level2', 'level3'])) {
// do something
}
您也可以将其与value(config,['applet',i,'height'])一起使用||42
CMS的ES6解决方案给了我这个想法。
还有一个非常紧凑的:
function ifSet(object, path) {
return path.split('.').reduce((obj, part) => obj && obj[part], object)
}
打电话:
let a = {b:{c:{d:{e:'found!'}}}}
ifSet(a, 'b.c.d.e') == 'found!'
ifSet(a, 'a.a.a.a.a.a') == undefined
它的性能不会很好,因为它拆分了一个字符串(但增加了调用的可读性),并遍历所有内容,即使已经很明显找不到任何内容(但提高了函数本身的可读性。
至少比get快http://jsben.ch/aAtmc
var a;
a = {
b: {
c: 'd'
}
};
function isset (fn) {
var value;
try {
value = fn();
} catch (e) {
value = undefined;
} finally {
return value !== undefined;
}
};
// ES5
console.log(
isset(function () { return a.b.c; }),
isset(function () { return a.b.c.d.e.f; })
);
如果您在ES6环境中编码(或使用6to5),则可以利用箭头函数语法:
// ES6 using the arrow function
console.log(
isset(() => a.b.c),
isset(() => a.b.c.d.e.f)
);
关于性能,使用try没有性能惩罚。。如果设置了属性,则捕获块。如果属性未设置,则会影响性能。
考虑简单地使用_.has:
var object = { 'a': { 'b': { 'c': 3 } } };
_.has(object, 'a');
// → true
_.has(object, 'a.b.c');
// → true
_.has(object, ['a', 'b', 'c']);
// → true
答案很多,但仍然是:为什么不更简单?
获取值的es5版本为:
function value(obj, keys) {
if (obj === undefined) return obj;
if (keys.length === 1 && obj.hasOwnProperty(keys[0])) return obj[keys[0]];
return value(obj[keys.shift()], keys);
}
if (value(test, ['level1', 'level2', 'level3'])) {
// do something
}
您也可以将其与value(config,['applet',i,'height'])一起使用||42
CMS的ES6解决方案给了我这个想法。