背景:
在最近的 NODEJS 项目中,涉及到数据库的查询,回调函数里返回了查询结果,我这样做处理然后返回给前端:
return results.collect_coupon[0].count
但是这样万一 results.collect_coupon 是 undefined,再继续取下去就会抛错(TypeError
),所以我激进地改成了这样:
return results && results.collect_coupon && results.collect_coupon[0] && results.collect_coupon[0].count
但是这种写法太过冗长,变量重复出现很不好维护。
[拓展]
这种写法会在从左到右的匹配中如果碰到 0、false、null、undefined,就终止匹配直接返回这个值。
例如:
console.log( 2 && 1 && 0 && false && null && undefined );
return:
0
解决方案:我封装了一个叫ignoreErrorAttr
的工具函数
/**
* 支持以字符串的方式取对象的属性或者数组的下标,如果中途取到undefined,就返回某个指定值(默认为空字符串)
*
* 作用:避免对undefined的继续向下取值,防止报TypeError错
*
* @param {object|array} obj 被取属性/下标的变量
* @param {string} search 取字符串
* @param {string} [re=""] 取值失败的默认返回值
* @returns
*/
function ignoreErrorAttr(obj, search = "", re = "") {
const arr = search.split(".");
if (!obj) {
return re;
}
for (let i = 0; i < arr.length; i++) {
if (arr[i].indexOf("[") >= 0 && arr[i].indexOf("]") >= 0) {
let index = arr[i].split("[")[1].split("]")[0]
obj = obj[index];
} else {
obj = obj[arr[i]];
}
if (obj === undefined) {
return re;
}
}
return obj;
}
test:
let obj = {a: {b: [1, 2]}};
console.log(ignoreErrorAttr(obj, "a.b.[1]"));
//2
console.log(ignoreErrorAttr(obj, "a.x.y.z","empty"));
//"empty"