解构赋值?
从数组、对象、字符串中提取值,对变量进行赋值,这种方法称之为“解构赋值”
解构赋值是对赋值运算符的扩展。
他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
解构模型
在解构中,有下面两部分参与:
- 解构的源,解构赋值表达式的右边部分。
- 解构的目标,解构赋值表达式的左边部分。
分类
1.数组的解构赋值
简单来说 [数组对应数组]
a.完全解构
let[a,b,c]=[1,2,3] //a 1 b 2 c 3
b.不完全结构
let [a,b]=[1,2,3] //a 1 b 2
c.结构不成功
let[foo]=1 //undefined
d.默认值:
如果一个数组成员是 null,默认值就不会生效,因为 null 不严格等于 undefined
let [x = 1] = [undefined]
let [x = 1] = [null]
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值
function f() {
return "我是函数的返回值";
}
let [x =f()] = ["我是新赋的值"];
console.log(x);
默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x=1, y = x] = []
let [x = y, y = 1] = []
2.对象的解构赋值
数组的元素是按次序排列的,变量的取值由它的位置决定;对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa" baz // "undefined"
a. 别名的引用
let { foo:bar } = { foo: 'aaa', baz: 'bbb' };
bar // "aaa"
b.解构也可用于嵌套结构的对象、
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let {p, p: [x, { y }] } = obj;
x // "Hello" y // "World" p // ["Hello", {y: "World"}]
c.对象的解构也可以指定默认值
var {x = 3} = {}
var {x, y = 5} = {x: 1}
d.★★默认值生效的条件是,对象的属性值严格等于 undefined★★。
var {x = 3} = {x: undefined}
var {x = 3} = {x: null}
3.字符串的解构赋值
a.字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] =
a // "h" b // "e" c // "l" d // "l" e // "o"
b.字符串属性解构
let {length : len} = 'hello'; len
4.函数参数的解构赋值
a. 函数参数的解构
function add([x, y]){
return x + y;
}
add([1, 2]);
b. 函数参数的解构使用默认值
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8});
move({x: 3});
move({});
5.数值和布尔值的解构赋值
应用
(1)交换变量的值
let x = 1
let y = 2
[x, y] = [y, x]
(2)从函数或数组返回变量的值
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
(3)函数参数的定义
(4)提取 JSON 数据
(5)函数参数的默认值
解构赋值是深拷贝还是浅拷贝?
深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型都是深拷贝。
浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型都是浅拷贝。
const a = {
name: 'John',
age: 18,
marriage: false,
addr: {
province: 'sichuan',
city: 'chengdu'
}
}
let {
name,
age,
marriage,
addr
} = a
name = 'rose'
age = 19
marriage = true
addr.province = 'shanghai'
addr.city = 'shanghai'
console.log(name, age, marriage, addr.city) //rose 19 true shanghai
console.log(a)

我们从对象a中解构赋值了name、age、marriage、addr四个变量,分别是string、number、boolean 、object类型。改变这四个变量的值后,再与a原来的值作对比,我们发现a的name,age,marriage属性没有改变,而addr属性发生了改变。由此可以得出结论,解构赋值对object类型只是浅拷贝。
实际上,无论是使用扩展运算符(...)还是解构赋值,对于引用类型都是浅拷贝。所以在使用splice()、concat()、...对数组拷贝时,只有当数组内部属性值不是引用类型是,才能实现深拷贝。(解构赋值是深拷贝还是浅拷贝? - 简书 (jianshu.com))