如果我有对象的引用:
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解决方案给了我这个想法。
我知道这个问题很古老,但我想通过将其添加到所有对象来提供一个扩展。我知道人们倾向于不赞成使用Object原型来实现扩展的对象功能,但我发现没有什么比这更容易的了。此外,现在还允许使用Object.defineProperty方法。
Object.defineProperty( Object.prototype, "has", { value: function( needle ) {
var obj = this;
var needles = needle.split( "." );
for( var i = 0; i<needles.length; i++ ) {
if( !obj.hasOwnProperty(needles[i])) {
return false;
}
obj = obj[needles[i]];
}
return true;
}});
现在,为了测试任何对象中的任何属性,只需执行以下操作:
if( obj.has("some.deep.nested.object.somewhere") )
这里有一个jsfiddle来测试它,特别是它包含一些jQuery,如果您直接修改Object.prototype,因为属性变为可枚举,则会中断。这对于第三方图书馆来说应该很好。
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