问题:
相信写前端的都遇到过这个问题,后台给你的数据undefined,然后你前端就报错,比如:
后台传输数据(打个比方):
a = [{
b:[{
c:xxxx
}]
}]
然后你就const data =a[0].b[0].c,或者用for循环循环a再循环b,但是呢,如果后台查不到a下面有数据,他就直接给你个a:[],这下好了,前端嘎嘎报错,“Uncaught TypeError: Cannot read properties of undefined”,我在网上也没找到啥解决办法,有的是写'?',比如 const data = a?.b?.c,但是吧,这个'?'他不能判断数组和最后一个值,就很蛋疼,于是,我想到了使用es6的proxy来解决这个问题
解决:
废话不说,上代码!
//proxy代理函数
const handler = {
get: function (obj:any, prop:any) {
//将获取的值赋给data,是object里面的值,proxy只能判断一层
let data = obj[prop]
//如果没有值
if (!data){
//将没有值的属性给一个空的对象
//注意,只要是能转成boolean的值,都会被替换成{},比如'',null,undefined等
data = new Proxy({}, handler)
}else{
//这里else里面是用来处理数组的,如果有值,不是数组或者是对象的话,直接返回数据
//proxy无法处理基本类型,如果不加这一行会报错
if (!(data instanceof Object) && !(data instanceof Array)){
return data;
}
//如果是数组或者对象,将数组或者对象的下一个属性的数据再进行一个处理
data = new Proxy(data, handler)
}
//返回最终数据
return data;
},
};
//最终使用的方法:例子:const data = toDefined(objectData)
const toDefined = (value:any) =>{
//先判断传来的是不是Object或者数组形式
if (!(value instanceof Object) && !(value instanceof Array)) return value
return new Proxy(value, handler)
}
使用示例:
//假设这是后台数据
const axiosData = [{
b:[{
c:'this is a axiosData'
}]
}]
//将后台数据通过方法代理,赋给一个新的变量
const data = toDefined(axiosData)
console.log(data[0].b[0].c); // this is a axiosData
console.log(data[0].b[0].d.e.f.g); // {}
//可以将data赋给其他的值,特性不变
const newData = data
console.log(newData[0].b[0].c); // this is a axiosData
console.log(newData[0].b[0].d.e.f.g); // {}
//深拷贝会报错(这不是废话嘛)
const deppCopyData = JSON.parse(JSON.stringify(data))
console.log(deppCopyData[0].b[0].c); //this is a axiosData
console.log(deppCopyData[0].b[0].d.e.f.g); // 报错
//还有几个会报错的,原因是 c 本来就有基本类型的值了
console.log(data[0].b[0].c.d.f) //报错,我想也不会有人这么写
console.log(newData[0].b[0].c.d.f) //报错,我想也不会有人这么写
问题算是解决了