一、何谓解构赋值?
1. 基本概念
首先我们看一下MDN给的定义
解构赋值语法是一个 Javascript 表达式,这使得可以将值从数组或属性从对象提取
到不同的变量中
从定义中,我们可以发现:
解构赋值的作用是对变量进行赋值
主要通过两个方面实现这个作用
- 数组【将数组中的值赋给变量】
let [a, b, c] = [0, 1, 2]
console.log(a, b, c) // 0 1 2
- 对象【将对象中
属性的值
赋给变量】
let obj = {a: 0, b: 1, c: 2}
// es5我们想把obj的值给取出来非常麻烦,而且obj的属性过多的话,还要进行遍历
let a = obj.a
let b = obj.b
let c = obj.c
// es6通过解构赋值就会非常简单
let {a: a, b: b, c: c} = obj
// 对象键值相同,可以只写一个【ES6提供的语法糖】,所以我们还可以简写成下面这个样子
let {a, b, c} = obj
console.log(a, b, c) // 0 1 2
2. 模式匹配
很多初学者都很难理解的问题是左边是数组/对象,右边也是数组/对象,是怎么进行匹配的呢?
其实这是对解构赋值一个非常大的误解。解构赋值的本质是模式匹配——只要等号两边的模式相同,左边的变量就会被赋予对应的值
所以表达式的左边并不是数组/对象,而是变量的集合,只不过它的模式要与数组/对象相对应,这里要特别强调的是对象的模式匹配还要保持键名【key】相同
那么现在我们就可以重新定义一下解构赋值了:把一些东西解放出来【解构】,按照模式匹配对应地赋值给其它变量
当然,上述示例适合于普通的变量声明,工作中我们会遇到许多特殊情况,这就需要解构赋值的特殊用法了
二、解构赋值的常见特殊用法
1. 给部分变量赋值
// 数组
let [a, , c, , e] = [1, 2, 3, 4, 5]
console.log(a, c, e) // 1 3 5
// 不适用于对象
2. 设置默认值
这里类似于函数默认参数值【ES6指北4有讲解,感兴趣的朋友可以去看看
】,先看个例子
// 数组
let [a, b, c, d] = [1, 2, 3]
console.log(d) // undefined
// 这里的d未被赋值,所以值为undefined
// 在这种情况我们可以像对函数参数设置默认值一样,对d也设置默认值
let [a, b, c, d = 4] = [1, 2, 3]
console.log(d) // 4
// 对象
let {a = {}, b = 1} = {a: undefined, b: 10}
console.log(a, b) // {} 10
3. 与函数返回值结合
// 数组
let f = () => [1, 2, 3]
let [a, b] = f()
console.log(a, b)
// 对象
let f = () => {
return {a: 0, b: 1, c: 2}
}
let {a, b} = f()
console.log(a, b) // 0 1
4. 与rest参数结合
// 数组
let [a, ...args] = [10, 2, 3, 4, 5]
console.log(args) // [2, 3, 4, 5]
// 对象
let {a, ...args} = {a: 10, b: 5, c: 3}
console.log(args) // {b: 5, c: 3}
5. 与函数参数结合
// 对象
function test({x: y = 2}) {
console.log(y)
}
// 等价于下面的形式
function test() {
let {x: y = 2} = arguments[0]
console.log(y)
}
// 这个时候你会发现,如果参数与结构赋值结合的话,等于对参数做出了数据类型【对象】的约束
// 比如,如果你传递的参数为字符串
test('asdf')
// 那么代码的逻辑是这样的
let {x: y = 2} = 'asdf' // 模式不匹配,解构失败
// 那么自然会报错了
// 如果你希望传递其它数据类型不报错的话,也很简单,为参数添加默认值就行【默认值为对象】
function test({x: y = 2} = {}) {
console.log(y)
}
// 数组
function test([a = 1, b = 2]) {
console.log(a, b)
}
三、练习题
练习一
let obj = {a: 1, b: 2, c: {d: {e: 5}}}
let {a, b, c: {d}} = obj
console.log(d) // ?
练习二
function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
console.log(size, cords, radius);
}
drawES2015Chart() // ?
drawES2015Chart({size: 'small', cords: {a: 1}, radius: {b: 1}}) // ?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。