今天项目经理说有一个问题,一个调了好几个接口的按钮报错了,赶紧打开看看,别人的代码,看起来还是有点麻烦,代码逻辑简化之后就如下面:
function fn(){
let a = {s:1};
let b = [{aa:1231}];
return{a,b};
}
function fn1(c,d){
fn2({c,d});
}
function fn2({a,b}){
console.log(a,b); //undefined undefined
}
function run(){
let {a,b} = fn();
fn1(a,b)
}
run();
第一眼看过去,没什么问题呀,打印出来的a,b都是undefined,定睛一看,fn2传入的参数是对象,a,b只是对象的元素,在fn1里面调用fn2时传的也是对象,只是里面的元素是c,d,那么在fn2中怎么可能拿得到a,b的值。
补充一下,这个是ES6中的解构赋值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
- 数组:本质上,只要等号两边模式一致,左边变量即可获取右边对应位置的值
let [a, b] = [1, 2]; //1 2
let [a,...b] = [1,2,3]; // 1 [2,3]
let [a,b,..c] = [1]; // 1 undefined []
- 对象:对象解构不需要严格按照顺序取值,而只要按照变量名去取对应属性名的值,若取不到对应属性名的值,则为undefined
let {a,b} = {a:1,b:2};//1 2
let {a:b} = {a:1,b:2};//b=>2 a报错
- 函数
function fun ({a=0, b=0} = {}){
return [a, b];
}
fun ({a:1, b:2}); // [1, 2]
fun ({a:1}); // [1, 0]
fun ({}); // [0, 0]
fun (); // [0, 0]
// 返回一个对象
function f (){
return {a:1, b:2};
}
let {a, b} = f();// a=>1, b=>2