ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

1.变量的解构赋值,即“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

以下两个赋值语句中,foo都属于解构不成功,等于undefined.

let [foo] = [];
let [bar, foo] = [1];

不完全解构,匹配等号右边的一部分变量:

let [a,b]=[1,2,3];
y //1
b //2

如果等号右边不是可遍历的结构,则会报错。(只要某种数据结构具有 Iterator 接口,就可以采用解构赋值)

// 报错
let [foo] = 1;

可以在等号左边使用默认值,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null
  1. 数组的解构中,对变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。、
let { foo ,bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

上面其实是下面的简写:

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};

let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}

上面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。
还可以嵌套赋值:

let obj = {};
let arr = [];

({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });

obj // {prop:123}
arr // [true]

注意:

// 报错,由于bar的父属性不存在
let {foo: {bar}} = {baz: 'baz'};

对象解构中默认值生效的条件同样为对象的属性值严格等于undefined。

var {x = 3} = {x: undefined};
x // 3

注意点

(1)如果要将一个已经声明的变量用于解构赋值

// 错误的写法,大括号放在行首js会将其理解成代码块
let x;
{x} = {x: 1};
// SyntaxError: syntax error

// 正确的写法
let x;
({x} = {x: 1});

(2)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

(3)字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

(4)数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
 posted on 2020-09-08 22:47  en、  阅读(230)  评论(0)    收藏  举报