大家知道,Javascript中,”=”的含义主要就是赋值,而有时候,简单的赋值也会让人产生误会。
在讲这种误会前,让我们先来做下下面的题吧!
一、抛砖引玉
砖头一:
function move(a = 1){
console.log(a);
}
move();
很简单,答案应该是1,对吧!原理如下:
function move(){
let a;//参数的声明
//以下是参数的赋值,考虑是否传了参数两种情况
if(arguments[0] === undefined){
a = 1;
}else{
a = arguments[0];
}
console.log(a);
}
move();
砖头二:
function move(a = {}){
console.log(a);
}
move();
这个跟砖头一是不是一模一样,只不过默认值变成了{},对吧!所以在这里就不过多讲述了!
砖头三:
当我们把形参a变成对象{x,y},会怎样呢?
function move({x,y} = {}){
console.log(x,y);
}
move();
这个结果是多少呢?答案是报错,对吗?看下原理:
function move({x,y} = {}){
let obj;
if(arguments[0] === undefined){
obj = {};
}else{
obj = arguments[0];
}
//而我们的实参确实不存在,所以obj就是{};
//那么{}传入函数体内,打印的是a和b,显示a,b未声明直接使用,所以报错
console.log(a,b);//未声明直接使用,报错
}
move();
前面三块砖,如果你做对了,那么,恭喜你,你已经成功入坑了!(鞭炮齐鸣,说明我的文章还有点价值)
二、璞玉归来
其实,造成之前的坑的原因,是因为你对解构赋值的原理不够了解(解构赋值不了解的同学请点击
https://blog.csdn.net/qq_17175013/article/details/81490923)
,让我们一起来探讨下这究竟是怎么回事吧!
function move({x,y} = {}){
let obj;
if(arguments[0] === undefined){
obj = {};
}else{
obj = {x,y};
}
let x = obj.x;
let y = obj.y;
console.log(x,y);//undefined,undefined
}
move();
显然,我们必须知道解构赋值的原理,即:
let {x,y} = {x:1,y:2};
//这个的原理是
let _obj = {x:1,y:2};
let x = _obj.x;
let y = _obj.y;
至此,我们可以来做下以下的题目:
题目一:
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
题目二:
function move({x = 0, y = 0} = {x:1}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [1, 0]
题目三:
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
其实,我们可以推导出一个通用原理,如下:
假设这个模型是这样的:
let a = '左侧x的默认值';
let b = '左侧y的默认值';
let p = '右侧x的值';
let q = '右侧y的值';
function move({x = a, y = b} = { x: p, y: q }) {
console.log(x,y);
}
>其原理就是:
function _move({_x = a, _y = b} = {_x : p, _y : q}){
let _obj;
if(arguments[0] === undefined){
obj = {_x:p,_y:q};//取默认值
}else{
obj = arguments[0];
}
let _x = obj.x;
if(_x === undefined){
_x = a;
}
let _y = obj.y;
if(_y === undefined){
_y = b;
}
console.log(_x,_y);
}
只要你懂得这个原理,那么你上面三个题目就能很快解答了!~
同时,我们也明白了形参{x = a, y = b} = { x: p, y: q }中的等号,其实并不是解构赋值的符号,而是默认值的符号。假如是最右边的等号是解构赋值的等号,那么实参传入,是需要形参接收的,显然右侧是实参,所以不可能是解构赋值的符号,那么自然就是默认值的符号,而左侧两个是默认值的符号显而易见,这里就不多做说明了。
图解如下: