ES6之解构赋值

ES6 的解构赋值为我们带来了一种全新的赋值方式,简介高效,但某些场景下如果使用不当反倒是一种混乱。

基础概念

解构赋值允许我们使用类似数组或对象字面量的语法形式将数组和对象的属性赋给各种变量。

1
2
3
4
5
6
7
8
// 传统赋值方式
let first = arr[0];
let seconde = arr[1];
let third = arr[2];
// 为各个变量解构赋值,注意不是给数组赋值
let [first, second, third] = arr;
// 或者
let [a. b. c] = [0, 1, 2];

需要注意的有以下几点:

  1. 如果解构赋值失败,待赋值变量的值为 undefined
  2. 赋值号左侧的模式只匹配赋值号右侧的部分模式,依然可以解构成功

    1
    let [a, b] = [1, 2, 3]
  3. 如果赋值号右侧的值不是可遍历的结构,即具备 Iterator 接口,那么赋值操作将会报错

  4. 解构赋值对于 varletconst 关键字声明的变量均适用

指定默认值

解构赋值允许制定默认值,示例如下:

1
2
let [a = 0] = [];
console.log(a); // 0

需要注意的有以下几点:

  1. 只有当用于赋值的数组成员的值严格等于(===) undefined 时,默认值才会生效
  2. 如果默认值是一个表达式,其将会被惰性求值,即只有用到它的时候,才会对其进行运算
  3. 默认值可以引用解构赋值的其他变量,但该变量必须之前已经声明过

解构对象

解构亦可用于对象,示例如下:

1
let { a, b } = { a: 0, bar: 1};

对象的解构与数组的解构主要区别是,对象的各个属性名必须与要赋值的变量名相同。本质上,对象的解构赋值,是在对象内部先找到同名属性,然后将属性值赋值给同名变量。

其他规则与数组的解构类似:

  1. 对象的解构也可指定默认值,生效条件是对象的同名属性值严格等于 undefined
  2. 如果解构失败,变量值为 undefined

值得注意的是,大括号单独写在行首时,JavaScript引擎会将其理解成一个代码块,解决方法是使用一个小括号将整个表达式包裹起来

字符串的解构

字符串也可用于解构赋值,这种场景下,字符串在后台被转换为了一个类似数组的对象:

1
2
let [ a, b, c ] = "ufo";
console.log(a, b, c); // "u" "f" "o"

圆括号问题

解构赋值的一个问题是,对于JavaScript引擎来说,语句到底是模式还是表达式,没有办法从一开始就判断,必须解析到(或解析不到)复制号时才能确定。

由此带来的问题是,如果模式中出现圆括号该怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。

不能使用圆括号的情况

  1. 变量声明语句中,不能带有圆括号
  2. 函数参数中,模式不能带有圆括号
  3. 赋值语句中,不能将整个模式或嵌套模式中的一层,放在圆括号之内

可以使用圆括号的情况

可以使用圆括号的情况只有一种:赋值语句的非模式部分。

1
2
[(a)] = [0];
( { a: (0) } = {} );

参考