JavaScript,检查嵌套对象属性是否为空/未定义的优雅方式
我时常遇到的一个“问题”是,我有一个对象,例如JavaScript,检查嵌套对象属性是否为空/未定义的优雅方式,javascript,object,javascript-objects,Javascript,Object,Javascript Objects,我时常遇到的一个“问题”是,我有一个对象,例如user={},在使用应用程序的过程中,这个对象会被填充。比如说,在AJAX调用之后,我会这样做: user.loc = { lat: 50, long: 9 } 在另一个地方,我想检查是否存在user.loc.lat if (user.loc.lat) { // do something } 如果它不存在,这将导致错误。如果user.loc.lat是未定义的,user.loc当然也是未定义的 "Cannot read p
user={}
,在使用应用程序的过程中,这个对象会被填充。比如说,在AJAX调用之后,我会这样做:
user.loc = {
lat: 50,
long: 9
}
在另一个地方,我想检查是否存在user.loc.lat
if (user.loc.lat) {
// do something
}
如果它不存在,这将导致错误。如果user.loc.lat
是未定义的
,user.loc
当然也是未定义的
"Cannot read property 'lat' of null" - Dev Tools error
这意味着我需要像这样检查它:
if (user.loc) {
if (user.loc.lat) {
// do something
}
}
get = function(obj, key) {
return key.split(".").reduce(function(o, x) {
return (typeof o == "undefined" || o === null) ? o : o[x];
}, obj);
}
或
这并不是很漂亮,我的对象越大,效果就越差——很明显(想象10个嵌套级别)。
让我有点恼火的是,if(user.loc.lat)
不仅仅返回false
ifuser.loc
也是未定义的
"Cannot read property 'lat' of null" - Dev Tools error
检查这种情况的理想方法是什么?好的,javascript有try-catch。根据您实际需要执行的操作(即,如果语句未定义,您的else
语句将是什么样子),这可能是您想要的
例如:
try {
user.loc.lat.doSomething();
} catch(error) {
//report
}
您可以使用lazy和
组合检查:
if(user.loc && user.loc.lat) { ...
或者,你用咖啡脚本。ES2020有了新的语法(空合并操作符)
这将运行对loc
属性的检查并防止空对象。如果(user&&user.loc&&user.loc.lat){…},请尝试此
您可以使用检查null和undefined的值
如果.loc
具有值false
,则可以尝试
if(user&&user.loc&&typeof(user.loc)!==“未定义”){…}
如果你有一个巨大的嵌套对象,你可以看看
函数checkNested(obj/*,level1,level2,…levelN*/){
var args=Array.prototype.slice.call(参数),
obj=args.shift();
对于(变量i=0;i
更新:
尝试使用以下实用程序功能:
if (user.loc) {
if (user.loc.lat) {
// do something
}
}
get = function(obj, key) {
return key.split(".").reduce(function(o, x) {
return (typeof o == "undefined" || o === null) ? o : o[x];
}, obj);
}
用法:
get(user, 'loc.lat') // 50
get(user, 'loc.foo.bar') // undefined
或者,仅检查属性是否存在,而不获取其值:
has = function(obj, key) {
return key.split(".").every(function(x) {
if(typeof obj != "object" || obj === null || ! x in obj)
return false;
obj = obj[x];
return true;
});
}
if(has(user, 'loc.lat')) ...
如果(user&&user.loc&&user.loc.lat){
您可以使用@AamirAfridi检查null和undefined的值,即使OP是这样写的,测试应该在最后一个对象而不是属性处停止。例如,如果user.loc.lat
存在但有一个错误值(例如0
),测试将返回false对不起,你们都回答得很快。这也是我想避免的一个例子。考虑到我有5到15级嵌套的巨大对象。我讨厌人们在不加评论的情况下投票。抱歉,你们的回答很快。你们的第一个方法也是我要避免的一个例子。o 15个嵌套级别。这里没有太多选项。(1)手动或使用CoffeeScript进行属性检查,(2)try/catch。如果您有一个具有15个嵌套级别的对象,并且它的属性在任何级别都可能不存在,那么我认为您的应用程序中存在一些次优设计模式。这是一个示例。我希望有一种方法可以涵盖这种情况。我显然会避免15个嵌套级别,但如果旧的服务器端应用程序只是这样做会怎么样我必须处理它?这就是为什么我想报道这个场景。我喜欢它!非常好的解决方案。get方法的问题是它可能会从链中的任何位置返回属性,它不会专门测试最后一个属性。@RobG怎么会这样?只要它碰到一个未定义的属性,它就会一路通过,结果就是未定义的。我希望LoaSug会有一个函数。<代码>。在异常情况下,您应该在不插入try-catch的情况下处理它。(当然,您可能会插入else子句)。我喜欢这种解决方案,因为简单的内容有时会因为条件而变得更难阅读。@JonasStensved指出在这个问题上不使用try-catch,因为启动异常(我认为,在编写抛出之前,您不会启动它)但问题可能是块中出现了其他错误,您将来将无法检测到它。@pikilon经验法则:不要将异常用于流控制。如果您的情况确实是意外的,则抛出异常。否则,将其作为任何其他代码条件处理。