变量的解构赋值

数组的结构赋值

let [a, [[b], c]] = [1, [[2], 3]];
console.log(a, b , c); // 1 2 3
let [a, , c] = [1, 2, 3];
console.log(a, c); // 1 3
let [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
let [a, b, ...c] = [1];
console.log(a); // 1
console.log(b); // undefined
console.log(c); // []

如果右边不是数组(不是可遍历的结构),解构会报错。

let [a] = null; // Uncaught TypeError: null is not iterable
let [a] = undefined; // Uncaught TypeError: undefined is not iterable
let [a] = false; // Uncaught TypeError: false is not iterable
let [a] = 1; // Uncaught TypeError: 1 is not iterable
let [a] = {}; // Uncaught TypeError: {} is not iterable

Set 结构也可以使用数组的解构赋值。

let [a] = new Set([1, 2, 3]);
console.log(a); // 1

只要有 Iterator 接口,都可以用数组的结构赋值。

function* fibs() {
  let a = 0;
  let b = 1;
  console.log(a, b); // 0 1
  while (true) {
    yield a;
    [a, b] = [b, a + b];
    console.log(a, b);
  }
}
let [first, second, third, fourth, fifth, sixth] = fibs();

默认值

可以指定默认值。

let [a = true] = [];
console.log(a); // true
let [a, b = 2] = [1];
console.log(a, b); // 1 2
let [a, b = 2] = [1, undefined];
console.log(a, b); // 1 2

当数组成员严格等于 undefined,默认值才会生效。

let [a] = [null];
console.log(a); // null

如果默认值是表达式,这个表达式是惰性求值的,只有用到时,才会求值。

function f() {
  console.log('a');
  return 'a';
}

let [a = f()] = [1];
console.log(a); // 1 注意 f() 不会执行

对象的解构赋值

let { a, b } = {a: 1, b: 2};
console.log(a, b); // 1 2

数组的解构是按顺序排列的,但是对象的解构没有顺序,变量名需与属性名相同,才能取到正确的值。

let { c } = {a: 1, b: 2};
console.log(c); // undefined

将现有对象的方法赋值给某个变量。

let { log } = console;
log('test'); // test
let { sin, cos } = Math;
console.log(sin(0), cos(0)); // 0, 1

变量名与属性名不一样。

let { a: b } = { a: 1 };
console.log(b); // 1

对象的解构也可以是嵌套的。

let obj = {
  a: [
    'Hello',
    {
      y: 'world',
    },
  ],
};

let { a: [x, { y } ] } = obj;
console.log(x, y); // Hello world

嵌套赋值

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

({ a: obj.a, b: arr[0] } = { a: 1, b: 2 });
console.log(obj); // {a: 1}
console.log(arr); // [2]

默认值

let { a = 1 } = {};
console.log(a); // 1

注意点

将已经声明的变量用于解构赋值,大括号不能位于行首。

// 会报错
let x;
{ x } = { x: 1}; // Uncaught SyntaxError: Unexpected token =
// 用括号括起来
let x;
({ x } = { x: 1});

可以对数组进行对象属性的解构。

const { length } = [1, 2, 3];
console.log(length); // 3

字符串的解构赋值

字符串可以解构赋值,是因为字符串被转换为类似数组的对象。

const [ a, b, c, d ] = '123456';
console.log(a, b, c, d); // 1 2 3 4

const { length } = '123456';
console.log(length); // 6

数值和布尔值的解构赋值

先将数值和布尔值转换为对象,再进行解构赋值。

如果右边是 null 和 undefined,因为无法转换为对象,所以对它们解构赋值会报错。

函数参数的解构赋值

function add([a, b]) {
  console.log(a + b);
}
add([1, 2]); // 3

用途

1、交换变量的值

let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y); // 2 1

2、从函数返回多个值

// 返回一个数组
function f() {
  return [1, 2, 3];
}
const [a, b, c] = f();
console.log(a, b, c); // 1 2 3
// 返回一个对象
function f() {
  return {
    a: 1,
    b: 2,
  };
}
const {a, b} = f();
console.log(a, b); // 1 2

3、函数参数的定义

// 有序的值
function f([a, b, c]) {
  // ...
}
f([1, 2, 3]);
// 无序的值
function f({a, b, c}) {
  // ...
}
f({c: 3, a: 1, b: 2});

4、提取 JSON 数据

const json = {
  name: 'name',
  age: 21,
  country: 'china',
};
const { name, age, country } = json;

5、函数参数的默认值

const fn = ({
  a: 1,
  b: 2
} = {}) => {
  // ...
}

6、遍历 Map 结构

const map = new Map();
map.set('first', 'Hello');
map.set('second', 'world');
for (let [key, val] of map) {
  console.log(`${key} is ${val}.`);
}
// first is Hello.
// second is world.

7、输入模块的指定方法

Last Updated: 5/6/2019, 4:26:15 PM