解构赋值
基本用法
解构赋值:允许按照一定模式,从数组和对象中提取值,对变量进行赋值。
const arr = [1, 2, 3]
// 普通赋值方式
const a1 = arr[0] // 1
const b1 = arr[1] // 2
const c1 = arr[2] // 3
// 解构赋值方式
const [a2, b2, c2] = arr // 1 2 3
总结
- 解构赋值属于
模式匹配
,只要等号左侧的模式
与右侧的结构
相同,左边的变量就会被赋予对应的值 - 解构赋值可以指定变量的默认值,如果解构不成功,变量的值等于该默认值,否则为
undefined
- 只要数据结构具有
Iterator
接口,都可以采用数组
形式的解构赋值,例:String
Set
Map
- 解构赋值重点是在
赋值
,赋值的元素是要拷贝出来赋值给变量,赋值的元素本身是不会被改变的
数组的解构赋值
const [a1, [[b1], c1]] = [1, [[2], 3]]
console.log(a1, b1, c1) // 1 2 3
const [a2, , c2] = [1, 2, 3]
console.log(a2, c2) // 1 3
const [a3, b3, c3 = 3] = [1]
console.log(a3, b3, c3) // 1 undefined 3
const [a4] = 1 // TypeError: 1 is not iterable
交换变量
ES5 临时变量
let a = 10
let b = 20
const tmp = a
a = b
b = tmp
console.log(a, b) // 20 10
ES6 解构赋值 推荐
let a = 10
let b = 20
const [b1, a1] = [a, b]
console.log(a1, b1) // 20 10
对象的解构赋值
对象的解构与数组有一个重要的不同点:数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
const { a, b, c } = { a: 1, b: 2 }
console.log(a, b, c) // 1 2 undefined
如果变量名和属性名不一致,可以在赋值模式中进行改名。
const { a1, b1 } = { a: 1, b: 2 }
console.log(a1, b1) // undefined undefined
// --------------------------
const { a: a2, b: b2 } = { a: 1, b: 2 }
console.log(a2, b2) // 1 2
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
注意
const { a: a2, b: b2 } = { a: 1, b: 2 }
console.log(a) // ReferenceError: a is not defined
console.log(b) // ReferenceError: b is not defined
这时前者的a
和b
是模式,不是变量,因此不会被赋值。
const { a, b } = { a: 1, b: 2 } // 简写形式
// 等价于
const { a: a, b: b } = { a: 1, b: 2 } // 完整形式
字符串的解构赋值
const [a, b, c, d, e] = 'hello'
console.log(a, b, c, d, e) // 'h' 'e' 'l' 'l' 'o'
其他值类型的解构赋值
- 只要等号右侧的值不是对象,就先将其包装转为对象,然后通过原型链查询相应的属性或方法
- 由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值都会报错
const { toString: numToStr } = 10
console.log(numToStr === Number.prototype.toString) // true
const { toString: boolToStr } = true
console.log(boolToStr === Boolean.prototype.toString) // true
const { toString: undefToStr } = undefined // Cannot destructure property 'toString' of 'undefined' as it is undefined.
const { toString: nullToStr } = null // Cannot destructure property 'toString' of 'null' as it is null.
Set 的解构赋值
const [a, b, c] = new Set([1, 2, 3])
console.log(a, b, c) // 1 2 3
Map 的解构赋值
const [a, b, c] = new Map().set('a', 1).set('b', 2).set('c', 3)
console.log(a, b, c) // ['a', 1] ['b', 2] ['c', 3]
函数参数的解构赋值
function add ([a, b]) {
return a + b
}
console.log(add([1, 2])) // 3
函数参数的解构也可以使用默认值,用于减少参数为undefined
的判断。
function move ({ x = 0, y = 0 } = {}) {
return [a, b]
}
console.log(move({ x: 1, y: 2 })) // [1, 2]
console.log(move({ x: 3 })) // [3, 0]
console.log(move({ })) // [0, 0]
console.log(move()) // [0, 0]