如何避免“不能读取未定义的属性”的错误?
在我的代码中,我处理了一个数组,其中有一些嵌套在另一个中的对象,有些则不这样。 它看起来如下所示:
// where this array is hundreds of entries long, with a mix // of the two examples given var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
这是给我的问题,因为我需要遍历数组有时,不一致是抛出我这样的错误:
for (i=0; i<test.length; i++) { // ok on i==0, but 'cannot read property of undefined' on i==1 console.log(abc); }
我知道我可以说, if(ab){ console.log(abc)}
,但是如果有多达5个或6个对象嵌套在一起,这是非常乏味的。 有没有其他(更简单)的方式,我可以只有做console.log如果存在,但没有抛出一个错误?
你正在做的事情引发了一个例外(正确如此)。
你可以随时做
try{ window.abc }catch(e){ console.log("YO",e) }
但我不会,而是想起你的用例。
你为什么要访问数据,6层嵌套,你不熟悉的? 什么用例certificate了这一点?
通常,你想实际validation你正在处理的是什么types的对象。
另外,在旁注中,不应该使用if(ab)
这样的语句,因为如果ab为0或即使为“0”,也将返回false。 而是检查ab !== undefined
如果我正确理解你的问题,你需要最安全的方式来确定一个对象是否包含一个属性。
最简单的方法是使用“in”语句。
window.a = "aString"; //window should have 'a' property //lets test if it exists if ("a" in window){ //true } if ("b" in window){ //false }
当然,你可以根据需要将其embedded深处
if ("a" in window.bc) { }
不知道这是否有帮助。
一个快速的解决方法是使用带ES6 箭头函数的try / catch辅助函数 :
function getSafe(fn) { try { return fn(); } catch (e) { return undefined; } } // use it like this getSafe(() => obj.a.lot.of.properties);
详情请参阅这篇文章 。
如果你正在使用lodash ,你可以使用他们的“has”function。 它与本地“in”类似,但允许path。
var testObject = {a: {b: {c: 'walrus'}}}; if(_.has(testObject, 'abc')) { //Safely access your walrus here }
当处理深层或复杂的json对象时,这是一个常见的问题,所以我尽量避免try / catch或embedded多个检查,这会使代码不可读,我通常在我的所有过程中使用这一小段代码来完成这项工作。
/* ex: getProperty(myObj,'aze.xyz',0) // return myObj.aze.xyz safely * accepts array for property names: * getProperty(myObj,['aze','xyz'],{value: null}) */ function getProperty(obj, props, defaultValue) { var res, isvoid = function(x){return typeof x === "undefined" || x === null;} if(!isvoid(obj)){ if(isvoid(props)) props = []; if(typeof props === "string") props = props.trim().split("."); if(props.constructor === Array){ res = props.length>1 ? getProperty(obj[props.shift()],props,defaultValue) : obj[props[0]]; } } return typeof res === "undefined" ? defaultValue: res; }
我虔诚地使用undefsafe 。 它testing每个级别到你的对象,直到它得到你要求的价值,或者它返回“未定义”。 但从来没有错误。
尝试这个。 如果ab
是未定义的,那么它将离开if
语句而没有任何exception。
if (ab && abc) { console.log(abc); }