如果我有对象的引用:
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);
}
但我想知道是否有更好的方法。
基于这个答案,我使用ES2015提出了一个通用函数,可以解决这个问题
function validChain( object, ...keys ) {
return keys.reduce( ( a, b ) => ( a || { } )[ b ], object ) !== undefined;
}
var test = {
first: {
second: {
third: "This is not the key your are looking for"
}
}
}
if ( validChain( test, "first", "second", "third" ) ) {
console.log( test.first.second.third );
}
function getValue(base, strValue) {
if(base == null) return;
let currentKey = base;
const keys = strValue.split(".");
let parts;
for(let i=1; i < keys.length; i++) {
parts = keys[i].split("[");
if(parts == null || parts[0] == null) return;
let idx;
if(parts.length > 1) { // if array
idx = parseInt(parts[1].split("]")[0]);
currentKey = currentKey[parts[0]][idx];
} else {
currentKey = currentKey[parts[0]];
}
if(currentKey == null) return;
}
return currentKey;
}
如果结果在嵌套或值本身的任何地方失败,则调用函数返回undefined
const a = {
b: {
c: [
{
d: 25
}
]
}
}
console.log(getValue(a, 'a.b.c[1].d'))
// output
25
我知道这个问题很古老,但我想通过将其添加到所有对象来提供一个扩展。我知道人们倾向于不赞成使用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,因为属性变为可枚举,则会中断。这对于第三方图书馆来说应该很好。