1、对象的解构赋值
1.1、给已经定义好的变量解构赋值问题
let a, b; {a, b} = {a: 123, b: 456}; // 报错显示:Uncaught SyntaxError: Unexpected token =
上面的代码将会报错,因为 JS 引擎遇到 {} 会当成一个代码块,语法规定,代码块语句不允许出现在赋值语句左侧,所以解构赋值时 { 不能出现在一行的最前面。在添加小括号后可以将块语句转化为一个表达式,从而实现整个解构赋值过程
let a, b; ({a, b} = {a: 123, b: 456}); console.log(a, b) // 123 456
1.2、解构赋值浅拷贝问题
解构赋值的拷贝是浅拷贝,如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。
let obj = { a: { b: 1 }, c: 100 }; let { ...x } = obj; //obj中 a 的值是对象,所以解构赋值时拷贝的是 a 的引用,而 c 的值是简单类型,所以obj.c改变不影响x obj.a.b = 2; obj.c = 200; console.log(x.a.b,c) // 2 100
2、函数参数的解构赋值
function move({x = 0, y = 0} = {}) { //{x=0,y=0}意思是x,y的默认值分别是0,后面的={}意思是如果函数没有传参时参数默认是{},而且由于前面给x,y默认值了,所以默认是{x=0,y=0},如果没有后面的={},这样调用:move()将会报错,但其他形式的调用不会有问题 return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, 0] move({}); // [0, 0] move(); // [0, 0]
下面的代码是为函数 move 的参数指定默认值,而不是为变量 x 和 y 指定默认值,所以会得到与前一种写法不同的结果。
function move({x, y} = { x: 0, y: 0 }) { //这样表示的是函数的参数默认是{x:0,y:0},但如果有参数的话即使参数只传x的值,此时默认值便不起作用 return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, undefined] move({}); // [undefined, undefined] move(); // [0, 0]