JavaScript中的结构赋值也是Mozilla项目率先提出和实现的。
解构赋值是从赋值运算符(=)右侧的对象或数组中提取值,对变量进行赋值。在解构赋值中,如果赋值运算符右侧部分不是数组或对象,就先将其转为对象,因此无法结构undefined和null。类型转换知识点传送门!!!
数组模型解构
解构赋值可以从赋值运算符右侧的数组中提取值,并按照对应的位置,对左侧的变量赋值。只要赋值运算符左右两侧的位置(或模式)对应,左侧的变量就能成功赋值。
let [a, b, c] = [1, 2, 3] // 等价于 let a=1, b=2, c=3
console.log(a, b, c) // 1 2 3
嵌套解构
// 允许嵌套,只要左右两侧的位置(模式)匹配即可
let [a, [b, [c]], d] = [1, [2, [3]], 4] // 等价于 let a=1, b=2, c=3, d=4
console.log(a, b, c, d) // 1 2 3 4
忽略值
// 忽略了值1和3
let [, x, , y] = [1, 2, 3, 4] // 等价于let x = 2, y = 4
console.log(x, y) // 2 4
不完全解构
// 不完全解构,右侧值的个数少于变量的个数
let [x, y] = [1] // 等价于let x = 1, y = undefined
剩余运算符
剩余运算符变量是个数组,相当于给数组赋值。
let [a, ...b] = [1, 2, 3]
a // 1
b // [2, 3]
解构可遍历对象
可遍历对象是实现Iterator接口的数据,可以理解为类数组数据,比如字符串,Set,dom中的NodeList等。
let [a, b, c] = 'JavaScript'
a // 'J'
b // 'a'
c // 'v'
let s = new Set()
s.add(1)
s.add(5)
s.add("some text")
let [x, y, z] = s
x // 1
y // 2
z // 'some text'
默认值
当解构模式有匹配结果,且匹配结果是undefined时,使用默认值。
let [a = 3] = [] // a首先匹配到undefined,使用默认值3
a // 3
let [b = 1, c = b] = [3] // b匹配到3,b=3;c匹配到undefined,使用c=b
b // 3
c // 3
let [d = 1, e = 1] = [5, 6] // d匹配到5,d=5;e匹配到6,e=6
d // 5
e // 6
对象模型解构
从赋值运算符右侧提取出key、value,并在赋值运算符左侧寻找相同的key,当寻找到相同的key后,会将左侧key对应的value当作变量名,并将右侧的value赋值给它。
基本用法
let {a, b} = {a: 1, b: 2} // 等价于let {a: a, b: b} = {a: 1, b: 2}
a // 1
b // 2
let {baz: foo} = {baz: 'foo'} // 等价于let foo = 'foo'
foo // 'foo'
// 两侧的key顺序可以不一致。
let {h: t, i: r} = {i: 'r', h: 't'}
t // 't'
r // 'r'
可嵌套
let obj = {p: ['hello', {y: 'world'}] }
let {p: [x, { y }] } = obj
/**
* 解构步骤
* 1. 按照对象模型解构,匹配p,得到[x, {y}] = ['hello', {y: 'world'}]
* 2. 将步骤1得到的结果按数组模型解构,得到x = 'hello'和 {y} = {y: 'world'}对象模型解构
* 3. 将步骤2得到的对象模型解构为 y = 'world'
*/
x // 'hello'
y // 'world'
可忽略
let obj = {p: {x: 'hello', q: {y: 'world'}} }
let {p: {x} } = obj
/**
* 解构步骤
* 1. 按照对象模型解构,匹配p,得到{x} = {x: 'hello', {y: 'world'}}
* 2. 将步骤1得到的结果按对象模型解构,得到x = 'hello',并将q: {y: 'world'}忽略
*/
x // 'hello'
不完全解构
let obj = {p: [{y: 'world'}] }
let {p: [{ y }, x ] } = obj
x // undefined
y // 'world'
剩余运算符
剩余运算符会将忽略的部分组合成新对象。
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a // = 10
b // = 20
rest // {c: 30, d: 40}
默认值
规则和数组模型解构的默认值相同。
let {a = 10, b = a} = {a: 3}
a // 3
b // 3
let {a: aa = 10, b: bb = 5} = {a: 50}
aa // 50
bb // 5
解构undefined和null
let { prop: x } = undefined
let { prop: y } = null
// TypeError: Cannot destructure property `prop` of 'undefined' or 'null'.
函数参数解构
function sum ([a = 3, b]) {
return a + b
}
sum([1, 2]) // 3
function multiply ({a, b = 4}) {
return a * b
}
multiply({a: 9}) // 36
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]