解构赋值--数组的解构赋值

什么是解构赋值?ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。我的理解是:允许声明一种模式(数组、对象等),里面包含一个或多个变量,再分别对这些变量遍历(按照对应位置)赋值。

数组解构赋值的基本用法

  以前,为变量赋值,只能直接指定值。

  let a = 1;

  let b = 2;

  通过解构赋值:

  let [a, b] = [1, 2]

  这和上面分别声明是一样的。从后面数组中按照对应位置分别给变量赋值,允许值比变量多,称为不完全解构,多出的部分不用管,如果变量比值多,则解构不成功,变量的值就是undefined,比如:

  let [a, b, c] = [1, 2, 3, 4, 5]

  a  //1  b  //2  c  //3   而4,5就不用管了;

  let [a, b, c,] = [1, 2]

  a //1  b //2  c //undefined

  但有一种情况,以...name这样声明的变量,虽然没有对应的值,也会为其赋值空(要看前面的前面的数据类型,比如空数组或空对象):

  let [a, b, ...c] = [1]

  a //1  b //undefined  c // []

  本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。

  let [a, [[b], c]] = [1, [[2, 3], 4]];

  a //1  b //2  c //4

  let [ , , str] = ['a', 'b', 'c']

  str // 'c'

  let [a, ...b] = [1, 2, 3, 4]    这中...name的形式叫做扩展运算符,后面再详细介绍。

  a //1  b //[2, 3, 4]

  如果等号右边不是数组(或者是不可以遍历的解构,需要参考 Iterator)就会报错,后面学习了再写吧,先举几个例子:

  let [a] = 1;

  let [a] = false;

  let [a] = NaN;

  let [a] = undefined;

  let [a] = null;

  let [a] = {};

  以上这些都会报错,因为等号右边的值(模式),转换成对象后不具备 Iterator 接口(前5个),要么本身就不具备 Iterator 接口(最后一个)。

  对于 Set 结构,也可以使用数组的解构赋值:

  Set结构:ES6提供的新的数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

  let [x, y, z] = new Set(['a', 'b', 'c']

  x //'a'  y //'b'  z //'c'

  事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

  function* fibs () {

    let a = 0;

    let b = 1;

    while (true) {

      yield a;

      [a, b] = [b, a+b];

    }

  }

  let [num1, num2, num3, num4, num5] = fibs();

  num5 //5

  上面代码中,fibs是一个 Generator 函数,原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。后面再详细介绍Generator函数。

默认值

  解构赋值允许指定默认值。就是在等式左边声明变量的时候就赋值,如果右边有对应位置又和默认值不一样的话,默认值就会被改变。

  let [foo = true] = [];

  foo //true;

  let [x, y = 'b'] = ['a'];

  x //'a'  y //'b'

  直接在左边声明变量等于undefined时,右侧对应位置没有值,得到的会是undefined,如果左边有默认值,有面对应位置是undefined,则还是取默认值,不会被undefined取代。上面说到到,如果左侧只声明为赋值,右侧也没有对应值,将取undefined。

  let [x = 1] = [undefined];

  x //1;

  let [x = 2] = [null];

  x //null

  上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined

  如果默认值是一个表达式,那将会在用到时候才会求值,这个表达式称为惰性求值。

  function f () {

    console.log('hello');

  }

  let [a = f()] = [1];

  上面这个代码,因为a能取到值,所以函数就不执行。

  默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

  let [x = 1, y = x] = [];  x = 1; y = 1;

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

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

  let [x = y, y = 1] = [1];  ReferenceError,报错为定义

  其实就是右侧有值的话,就会改变对应左侧位置的变量的值,但默认值但变量需要提前声明,否则就会报错,就是变量第一次出现时,不能出现在‘=’右侧,比如最后这个。

posted @ 2017-10-30 11:27  博客-崔  阅读(2604)  评论(0编辑  收藏  举报