28

一、何谓解构赋值?

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】相同
clipboard.png

clipboard.png

那么现在我们就可以重新定义一下解构赋值了:把一些东西解放出来【解构】,按照模式匹配对应地赋值给其它变量

当然,上述示例适合于普通的变量声明,工作中我们会遇到许多特殊情况,这就需要解构赋值的特殊用法了

二、解构赋值的常见特殊用法

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}}) // ?

bluesboneW
784 声望79 粉丝

今天,你帮助了社区