如果我有对象的引用:
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);
}
但我想知道是否有更好的方法。
我认为下面的脚本提供了更可读的表示。
声明函数:
var o = function(obj) { return obj || {};};
然后这样使用:
if (o(o(o(o(test).level1).level2).level3)
{
}
我称之为“悲伤小丑技巧”,因为它使用了符号o(
编辑:
这是TypeScript的版本
它在编译时提供类型检查(如果使用像Visual Studio这样的工具,还提供智能感知)
export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
if (typeof someObject === 'undefined' || someObject === null)
return defaultValue;
else
return someObject;
}
用法相同:
o(o(o(o(test).level1).level2).level3
但这次intelligense奏效了!
此外,您可以设置默认值:
o(o(o(o(o(test).level1).level2).level3, "none")
另一种解决方法是,例如,使用以下对象:
var x = {
a: {
b: 3
}
};
然后,我所做的是向这个对象添加以下函数:
x.getKey = function(k){
var r ;
try {
r = eval('typeof this.'+k+' !== "undefined"');
}catch(e){
r = false;
}
if(r !== false){
return eval('this.'+k);
}else{
console.error('Missing key: \''+k+'\'');
return '';
}
};
然后您可以测试:
x.getKey('a.b');
如果未定义,则函数返回“”(空字符串),否则返回现有值。
还请考虑检查链接的另一个更复杂的解决方案:JS对象具有属性深度检查
Object.prototype.hasOwnNestedProperty = function(propertyPath){
if(!propertyPath)
return false;
var properties = propertyPath.split('.');
var obj = this;
for (var i = 0; i < properties.length; i++) {
var prop = properties[i];
if(!obj || !obj.hasOwnProperty(prop)){
return false;
} else {
obj = obj[prop];
}
}
return true;
};
// Usage:
var obj = {
innerObject:{
deepObject:{
value:'Here am I'
}
}
}
obj.hasOwnNestedProperty('innerObject.deepObject.value');
注:还有一个递归版本。
下面是我的看法-这些解决方案中的大多数都忽略了嵌套数组的情况,如:
obj = {
"l1":"something",
"l2":[{k:0},{k:1}],
"l3":{
"subL":"hello"
}
}
我可能想检查obj.l2[0].k
使用下面的函数,您可以执行深度测试('l2[0].k',obj)
如果对象存在,函数将返回true,否则返回false
函数deeptest(keyPath,testObj){变量obj;keyPath=keyPath.split('.')var cKey=keyPath.shift();函数get(pObj,pKey){var bracketStart,bracketEnd,o;bracketStart=pKey.indexOf(“[”);if(bracketStart>-1){//检查嵌套数组bracketEnd=pKey.indexOf(“]”);var arrIndex=pKey.substr(bracketStart+1,bracketEnd-bracketStart-1);pKey=pKey.substr(0,括号开始);var n=pObj[pKey];o=n?n[arrIndex]:未定义;}其他{o=pObj[pKey];}返回o;}obj=获取(testObj,cKey);while(obj&&keyPath.length){obj=get(obj,keyPath.shift());}返回typeof(obj)!=='未定义';}变量obj={“l1”:“级别1”,“arr1”:[{“k”:0},{“k”:1},{“k”:2}],“子”:{“a”:“字母a”,“b”:“字母b”}};console.log(“l1:”+深度测试(“l1”,obj));console.log(“arr1[0]:”+深度测试(“arr1[0]”,obj));console.log(“arr1[1].k:”+深度测试(“arr1].k”,obj));console.log(“arr1[1].j:”+深度测试(“arr1].j”,obj));console.log(“arr1[3]:”+深度测试(“arr1[3]”,obj));console.log(“arr2:”+深度测试(“arr2”,obj));