es6作为新一代js的标准,已经被广泛应用于各个场景,所以,熟悉并熟练使用它变得非常有必要。

本篇介绍变量的解构赋值中的数组部分,后续会介绍其他部分

我们先来了解一下解构赋值:es6允许按照一定的模式从对象或数组中提取值,然后对变量进行赋值,这被称为解构赋值。

来看个实际项目中的案例:

const server = {
    ip:127.0.0.1,
    port:3000
}

// 常规写法:
const ip = server.ip;
const port = server.port;

// 解构赋值写法:
const { ip, port } = server;

这样无疑会大大优化我们复杂的代码结构,并清晰明了的得到所需要的值。

以下将通过大量的demo,介绍数组的解构赋值(注:案例来源于 " es6标准入门 " 这本书,每个都是博主自己手敲学习过的)

// 以前为变量赋值只能直接指定值
  let a = 1;
  let b = 2;
  let c = 3;
  // es6允许写成下面这样:从数组中提取值,然后对应位置对变量赋值
  let [d, e, f] = [4, 5, 6];

  console.log(a,b,c,d,e,f);   // 1, 2, 3, 4, 5, 6

  // 实质上,这种写法属于‘模式匹配’,只要等号两边的模式相同,左边的变量就会被赋予对应的值

  // 下面是一些使用嵌套数组进行解构的例子:

  let [foo, [[bar], baz]] = [1, [[2], 3]];
  console.log(foo, bar, baz);   // 1, 2, 3

  let [ , , three] = ['foo', 'bar', 'baz'];
  console.log(three);   // baz

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

  let [head, ...tail] = [1, 2, 3, 4];
  console.log(head, tail);    // 1, [2, 3, 4]

  // 如果解构不成功,变量的值等于undefined
  let [g, h, ...i] = ['a'];
  console.log(g, h, i);   // a, undefined, []

  let [name] = [];
  console.log(name);      // undefined
  let [sex, age] = [1];
  console.log(sex, age);     // 1, undefined

  // 不完全解构,即等号左边的模式只匹配一部分的等号右边的数组,但是依然可以解构成功
  let [m, n] = [1, 2, 3];
  console.log(m, n);      // 1, 2

  let [Q, [W], E] = [1, [2, 3], 4];
  console.log(Q, W, E);   // 1, 2, 4

  // 如果等号右边不是数组(或者严格来说不是可遍历的结构),那么将会报错
  // 以下代码都会报错,因为等号右边的值或是转为对象后不具备Iterator接口(前5个表达式),或是本身就不具备Iterator接口(最后一个表达式)
  let [t] = 1;
  let [t] = false;
  let [t] = NaN;
  let [t] = undefined;
  let [t] = null;
  let [t] = {};

  // 对于Set结构,也可以使用数组的解构赋值
  let [A, B, C] = new Set(['a', 'b', 'c']);
  console.log(A, B, C);     // a, b, c

  // 事实上,只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值
  function* fibs() {
    let w = 0;
    let j = 1;
    while (true) {
      yield w;
      [w, j] = [j, w + j];
    }
  }

  let [first, second, third, fourth, fifth, sixth] = fibs();
  console.log(first, second, third, fourth, fifth, sixth);    // 0, 1, 1, 2, 3, 5

  // 解构赋值允许指定默认值

  // es6内部严格使用相等运算符 === 判断一个位置是否有值,如果一个数组成员不严格等于undefined,默认值是不会生效的

  let [boo = true] = [];
  console.log(boo);   // true

  let [X, Y = 'b'] = ['a'];
  console.log(X, Y);    // a, b

  let [M, N = 'b'] = ['a', undefined];
  console.log(M, N);    // a, b

  let [s = 1] = [undefined];
  console.log(s);   // 1

  let [k = 1] = [null];
  console.log(k);   // null:因为null不严格等于undefined,所以默认值不会生效,null会替换默认值

  // 如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到时才会求值
  function u() {
    console.log('aaa');
  }
  let [l = u()] = [1];
  console.log(l);   // 1:因为l能取到值,所以函数u根本不会执行
  /* 等价于:
    let l;
    if ([1][0] === undefined) {
      l = u();
    } else {
      l = [1][0]
    }
  */

  // 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
  let [AA = 1, BB = AA] = [];
  console.log(AA, BB);    // 1, 1

  let [CC = 1, DD = CC] = [2];
  console.log(CC, DD);    // 2, 2
  
  let [EE = 1, FF = EE] = [1, 2];
  console.log(EE, FF);    // 1, 2

  let [GG = HH, HH = 1] = [];
  console.log(GG, HH);    // 报错:因为GG用到默认值HH时,HH还没有声明

以上,就是数组解构赋值常用的一些场景,能便捷的解决我们很多的问题。

对象的解构赋值:对象的解构赋值

变量的解构赋值 - 字符串、数值、布尔值、函数参数:变量的解构赋值 - 字符串、数值、布尔值、函数参数

如有问题,请指出,接受批评。