是否有一种简单的方法可以本地确定JavaScript中对象中是否存在深层属性?例如,我需要访问这样的属性:
var myVal = appData.foo.bar.setting;
但是有可能还没有定义foo,foo.bar或foo.bar.setting。在Groovy中,我们可以这样做:
def myVal = appData?.foo?.bar?.setting
有没有类似的方法在JavaScript中执行此操作,而无需编写自定义函数或嵌套if语句?我发现this answer很有用,但我希望有更优雅,更少自定义的方式。
答案 0 :(得分:16)
我觉得这很方便:
var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;
如果存在属性,则将尝试序列的下一部分。
当&&
之前的表达式求值为false时,不会检查表达式的下一部分。如果未定义myVal.appData.foo.bar.settings
中的任何一个,则myVal
的值undefined
(将评估为false
。
答案 1 :(得分:5)
抱歉,这不太好:
var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;
另一种选择:
try {
var myVal = appData.foo.bar.setting;
} catch (e) {
var myVal = undefined;
}
。 operator不是真正用于访问这样的对象。可能使用函数是个好主意。
答案 2 :(得分:3)
我发现其他方法有点巨大。那么,以下方法的主要缺点是什么:
// Pass the path as a string, parse it, and try to traverse the chain.
Object.prototype.pathExists = function(path) {
var members = path.split(".");
var currentMember = this;
for (var i = 0; i < members.length; i++) {
// Here we need to take special care of possible method
// calls and arrays, but I am too lazy to write it down.
if (currentMember.hasOwnProperty(members[i])) {
currentMember = currentMember[members[i]];
} else {
return false;
}
}
return true;
}
基本上,我们在对象上定义一个方法(不一定),该方法获取嵌套对象的路径并返回存在确认,如appData.pathExists("foo.bar.setting");
编辑:
检查object[prop] == undefined
在语义上不正确,因为即使属性已定义,它也将返回false,尽管其值为undefined
;这就是我使用hasOwnProperty
来检查属性的原因。如果需要获取值,这可能并不重要。
答案 3 :(得分:2)
如果,在:
之后var myVal = appData.foo && appData.foo.bar && appData.foo.bar.setting;
myVal
不是undefined
,它会保留appData.foo.bar.setting
的值。
答案 4 :(得分:1)
你可以试试这个
var x = {y:{z:{a:'b'}}}
x && x.y && x.y.z && x.y.z.a //returns 'b'
这不如groovy表达式好,但它有效。在遇到第一个未定义变量后,评估停止。
答案 5 :(得分:1)
var product = ...,
offering = (product||{}).offering,
merchant = (offering||{}).merchant,
merchantName = (merchant||{}).name;
if (merchantName)
displayMerchantName(merchantName);
答案 6 :(得分:0)
我刚刚做了这个,所以它可能无法正常工作,我还包括两个测试用例。
function hasPropertyChain(o, properties) {
var i = 0,
currentPropertyChain = o;
if(!o) {
return false;
}
while(currentPropertyChain = currentPropertyChain[properties[i++]]);
return i - 1 === properties.length;
}
alert(hasPropertyChain({a:{b:{c:'a'}}}, ['a','b','c'])); // true
alert(hasPropertyChain({a:{b:{c:'a'}}}, ['a','b','c', 'd'])); // false