如果我有对象的引用:
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版本@CMS的优秀答案:
// Check the obj has the keys in the order mentioned. Used for checking JSON results.
var checkObjHasKeys = function(obj, keys) {
var success = true;
keys.forEach( function(key) {
if ( ! obj.hasOwnProperty(key)) {
success = false;
}
obj = obj[key];
})
return success;
}
通过类似测试:
var test = { level1:{level2:{level3:'result'}}};
utils.checkObjHasKeys(test, ['level1', 'level2', 'level3']); // true
utils.checkObjHasKeys(test, ['level1', 'level2', 'foo']); // false
我知道这个问题很古老,但我想通过将其添加到所有对象来提供一个扩展。我知道人们倾向于不赞成使用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,因为属性变为可枚举,则会中断。这对于第三方图书馆来说应该很好。
//Just in case is not supported or not included by your framework
//***************************************************
Array.prototype.some = function(fn, thisObj) {
var scope = thisObj || window;
for ( var i=0, j=this.length; i < j; ++i ) {
if ( fn.call(scope, this[i], i, this) ) {
return true;
}
}
return false;
};
//****************************************************
function isSet (object, string) {
if (!object) return false;
var childs = string.split('.');
if (childs.length > 0 ) {
return !childs.some(function (item) {
if (item in object) {
object = object[item];
return false;
} else return true;
});
} else if (string in object) {
return true;
} else return false;
}
var object = {
data: {
item: {
sub_item: {
bla: {
here : {
iam: true
}
}
}
}
}
};
console.log(isSet(object,'data.item')); // true
console.log(isSet(object,'x')); // false
console.log(isSet(object,'data.sub_item')); // false
console.log(isSet(object,'data.item')); // true
console.log(isSet(object,'data.item.sub_item.bla.here.iam')); // true
function propsExists(arg) {
try {
const result = arg()
if (typeof result !== 'undefined') {
return true
}
return false
} catch (e) {
return false;
}
}
此函数还将测试0,null。如果他们在场,它也将返回真实。
例子:
函数propsExists(arg){尝试{常量结果=arg()if(结果类型!==“undefined”){返回true}return false}捕获(e){return false;}}让obj={测试:{a: 空,b: 0,c: 未定义,d: 4中,e: “嘿”,f: ()=>{},g: 5.4中,h: 假,i: 真的,j: {},k: [],我:{a: 1中,}}};console.log('obj.test.a',propsExists(()=>obj.test/a))console.log('obj.test.b',propsExists(()=>obj.test.b))console.log('obj.test.c',propsExists(()=>obj.test.c))console.log('obj.test.d',propsExists(()=>obj.test-d))console.log('obj.test.e',propsExists(()=>obj.test.ex))console.log('obj.test.f',propsExists(()=>obj.test-f))console.log('obj.test.g',propsExists(()=>obj.test/g))console.log('obj.test.h',propsExists(()=>obj.test.h))console.log('obj.test.i',propsExists(()=>obj.test-i))console.log('obj.test.j',propsExists(()=>obj.test.j))console.log('obj.test.k',propsExists(()=>obj.test.k))console.log('obj.test.l',propsExists(()=>obj.test/l))