JS在读取json中的值时,遇见undefined字段时的处理
从前
有个前端公陈尸正在开发微信小程序,
服务器端和前端约定好一个接口应该返回这样一个json:
'{"res":{"data":{"userInfo":{"card":{"name":"zhangyin"}}}}}';
于是,前端在收到服务器端返回的json后这样写到:
var name = res.data.userInfo.card.name;
var title = "hello " + name;
通常,上面这样写是ok的。
不过,后来服务器端同学重构代码时,发现某个用户并没有card数据,于是在返回的数据就变成了以下这样:
{"res":{"data":""}}
于是,前端代码在执行到这句时就发生error了:
var name = res.data.userInfo.card.name;
并且后面的代码也不会继续执行了,如果后续代码有一些很重要的逻辑也会被错过了。
而且前端用户也无法看到相应的错误处理提示;
我们可以使用try ... catch来捕获错误,然后进行处理;
也可以对json中的逐个层级来进行if判断。
总之代码写起来都会比较啰嗦,
有时,写代码到hight处时,会忘记写这些判断;
所以,我想要不就写个函数来专门检查这种字段缺失导致的错误吧。
结果发现,当发生这种 在多个json层级中丢失字段的情况 时,
程序在检查函数被调用起来前就出错了,
无法将res.data.userInfo.card.name作为一个参数传到函数里;
于是乎,
我就花了2秒钟胡乱写了一个方法,试图找到一个简便的处理方式。
这个方法纯属狗皮膏药式的,难免错漏,
贴出来仅供大家一乐,不要被我误导~~
/**
* 返回一个json层级下的节点内容
* root : 要被读取的json节点的root节点
* jsonStr : 要被读取的节点的字符串形式
* defaultValue : 如果要被读取的节点不存在或为空,则返回该值
*
* // demo
* var jsonStr = '{"res":{"data":null}}';
* var jsonRoot = JSON.parse(jsonStr);
* var str = utils.jsonObj(jsonRoot,"res.data.userInfo.card.name",undefined);
*/
function jsonObj(root, jsonStr,defaultValue) {
if (!root) {
return defaultValue;
} else {
try {
var nodeNameArray = jsonStr.split('.');
var tmpRoot = root;
var i = 0;
for (var i = 0; i < nodeNameArray.length; i++) {
var tmpNodeName = nodeNameArray[i];
var tmpNode = tmpRoot[tmpNodeName];
if (tmpNode) {
console.log("." + tmpNodeName);
tmpRoot = tmpNode;
} else {
//发生异常了
console.log("解析失败," + jsonStr + " 的值为:" + defaultValue);
return defaultValue;
}
}
//解析完成,tmpRoot即为所求
console.log(jsonStr + " 的值为:"+tmpNode);
return tmpNode;
} catch (e) {
console.log("try catch." + e);
return defaultValue;
}
}
}
看到这里,有人肯定会问:
这不是脱裤子放屁吗?
前端该如何解析json,难道不是事先就和server端同学商定好了的吗?
服务端如果不按照事先的约定返回,那是服务端同学的问题啊?
让服务端同学去改一下不就OK了?
的确,道理我都懂,就是过不好这一生。
当有前端+后端配合开发的项目时,很多错误都是通过前端系统被暴露出来的,
特别是线上的项目,
有时候错误是很灵异的,需要很多精力去排查,最后才能发现问题所在。
我认为加一层处理的好处是:应该可以提高排错的速度。
另外,对于线上的系统,
多一层防护,
无论对用户体验还是对系统本身,都会更好一些吧~
全剧终...