解构赋值在开发中很常用,在此总结它的用法…
什么是解构?
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。它在语法上比 ES5 所提供的更加简洁、紧凑、清晰。它不仅能减少你的代码量,还能从根本上改变你的编码方式。
数组解构
以前,为变量赋值,我们只能直接指定值,比如
1 2 3
   | let a = 1 let b = 2 let c = 3
   | 
现在可以用数组解构的方式来进行赋值
1 2
   | let [a, b, c] = [1, 2, 3] console.log(a, b, c) 
   | 
这是数组解构最基本类型的用法,还可以解构对象数组
1 2 3
   |  let [a, b, c] = [{ name: 'jacky' }, { name: 'monkey' }, { name: 'houge' }] console.log(a, b, c) 
 
  | 
数组模式和赋值模式统一
这条可以理解为等号左边和等号右边的形式要统一,如果不统一解构将失败。
1 2 3 4 5 6 7 8 9 10 11 12
   | let [a, [b, c], d] = [1, [2, 3], 4] console.log(a, b, c, d) 
 
  let [a, , , d] = [1, 2, 3, 4] console.log(a, d) 
  let [a, ...b] = [1, 2, 3, 4] console.log(a, b) 
  let [a, , , ...d] = [1, 2, 3, 4, 5] console.log(a, d) 
   | 
如果解构不成功,变量的值就等于undefined
1 2 3 4 5
   | let [a, b, c] = [2, 3] console.log(a, b, c) 
  let [c] = [] console.log(c) 
   | 
上述是完全解构的情况,还有一种是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组,解构依然可以成功。
1 2 3 4 5
   | let [x, y] = [1, 2, 3] console.log(x, y) 
  let [a, [b], d] = [1, [2, 3], 4] console.log(a, b, d) 
   | 
解构的默认值
解构赋值允许指定默认值。
1 2 3 4 5
   | let [a, b = 2] = [1] console.log(a, b) 
  let [a = 1, b = 2, c, d = 13] = [10, 11, 12] console.log(a, b, c, d) 
   | 
对象的解构赋值
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   |  let obj = { a: 'aaa', b: 'bbb' } let { a: x, b: y } = obj console.log(x, y) 
  let { a, b } = { a: 'aaa', b: 'bbb' } console.log(a, b) 
 
  let { b, a } = { a: 'test1', b: 'test2' } console.log(a, b) 
 
  let {   obj: { name }, } = { obj: { name: 'jacky', age: '22' } } console.log(name) 
 
  let obj = {   p: ['Hello', { y: 'World' }], }
  let {   p: [x, { y }], } = obj console.log(x, y) 
 
  | 
如果变量名与属性名不一致,必须写成下面这样。
1 2 3
   | var { foo: rename } = { foo: 'aaa', bar: 'bbb' } console.log(rename)  console.log(foo) 
  | 
如果在解构之前就定义了变量,这时候再解构会出现问题。下面是错误的代码,编译会报错(因为 js 引擎会将{a}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 js 将其解释成代码块,才能解决这个问题)
1 2 3
   | let a; let obj = { a: "aaa" }; {a} = obj; 
   | 
要解决报错,使程序正常,这时候只要在解构的语句外边加一个圆括号就可以了
1 2 3 4
   | let a let obj = { a: 'aaa' } ;({ a } = obj) console.log(a) 
   | 
函数参数
函数的参数也可以使用解构赋值。
1 2 3 4 5
   | function add([x, y]) {   return x + y }
  add([1, 2]) 
  | 
函数参数的解构也可以使用默认值。
1 2 3 4
   | function fn(x, y = 7) {   return x + y } console.log(fn(3)) 
  | 
字符串解构
字符串被转换成了一个类似数组的对象。
1 2 3 4 5 6 7
   | const [a, b, c, d, e, f] = 'hello' console.log(a)  console.log(b)  console.log(c)  console.log(d)  console.log(e)  console.log(f) 
   | 
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
1 2 3 4 5
   | let { toString: s } = 0 console.log(s === Number.prototype.toString) 
  let { toString: s } = true console.log(s === Boolean.prototype.toString) 
  | 
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
1 2
   | let { prop: x } = undefined  let { prop: y } = null 
  | 
解构赋值的应用
交换变量的值
通常交换两个变量的方法需要一个额外的临时变量,如下
1 2 3 4 5 6 7 8 9
   | let a = 1 let b = 2 let temp
  temp = a a = b b = temp
  console.log(a, b) 
   | 
用 ES6 解构赋值的话,会变得很简洁
1 2 3 4 5
   | let a = 1 let b = 2 ;[a, b] = [b, a]
  console.log(a, b) 
   | 
从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   |  function example() {   return [1, 2, 3] } let [a, b, c] = example()
 
  function example() {   return {     foo: 1,     bar: 2,   } } let { foo, bar } = example()
 
  | 
访问数组中元素
有种场景,比如有一个数组(可能为空)。并且希望访问数组的第一个、第二个或第 n 个项,但如果该项不存在,则使用指定默认值。
通常会使用数组的length属性来判断
1 2 3 4 5 6 7 8
   | const list = []
  let firstItem = 'hello' if (list.length > 0) {   firstItem = list[0] }
  console.log(firstItem) 
   | 
如果用 ES6 解构赋值来实现上述逻辑
1 2 3 4
   | const list = [] const [firstItem = 'hello'] = list
  console.log(firstItem) 
   | 
提取 JSON 数据
1 2 3 4 5 6 7 8 9 10
   | let jsonData = {   id: 42,   status: 'OK',   data: [867, 5309], }
  let { id, status, data: number } = jsonData
  console.log(id, status, number)
 
  | 
遍历 Map 结构
任何部署了 Iterator 接口的对象,都可以用for...of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
1 2 3 4 5 6 7 8 9
   | const map = new Map() map.set('first', 'hello') map.set('second', 'world')
  for (let [key, value] of map) {   console.log(key + ' is ' + value) }
 
 
   | 
如果只想获取键名,或者只想获取键值,可以写成下面这样。
1 2 3 4 5 6 7 8 9
   |  for (let [key] of map) {    }
 
  for (let [, value] of map) {    }
 
  | 
- 文章部分内容参考:阮一峰老师的《ECMAScript 6 入门》一书