如何避免“不能读取未定义的属性”的错误?

在我的代码中,我处理了一个数组,其中有一些嵌套在另一个中的对象,有些则不这样。 它看起来如下所示:

// 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); }