您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

ES6+ 解构赋值

本节我们会学习到 ES6 中的解构赋值语法,它是 JavaScript 中的一种表达式。在本节中你可以了解以下:

解构赋值就是分解数据的结构,并从这数据解构中数据的过程,它可以从数组中取出值赋给变量或是将对象中的出来赋给另对象的。解构的目的是为了简化数据的过程,增强的可读性。 把变量放在 [] 或者 {} 中来目标对象上的对应的值。

数组的解构赋值是,通过新建数组,数组内的变量和目标数组是一一对应的,按照索引的方式去值,然后赋值给指定索引上的变量。在 ES6 之前,想数组中的值,需要通过 Array[index] 的方式来值,这种方式的好处在于可以数组上指定索引的值,如果我们想把数组的每一项的值都取出来,赋给变量,这样的写法就显得很笨拙:

var arr = [, ];
console.log(arr[]);  // 10
console.log(arr[]);  // 20

上面的取值方式是 ES6 之前的写法,有了 ES6 的解构赋值就简单了很多,下面看 ES6 解构赋值是怎么取数组的对应值的:

var [a, b] = [, ];
console.log(a);   // 10
console.log(b);   // 20

上面的例子中先声明数组,分别在数组的 0 和 1 的索引位置上放置变量 a 和 b,对应着需要数组的索引位置,这样就可以从数组当中取到我们想要的值了。

在解构未知的数组时,需要对未能取的值的变量赋认值,为了防止从数组中取出值为 undefined 的对象,可以在表达式的左边的数组中为任意变量预设认的值。

let [a=, b=] = [];             // a=1 b=9
let [a, b = ] = [, ''];        // a=10, b=''
let [a, b = ] = [, undefined]; // a=10, b=1

Tips: 在 ES6 中,判断数组中是否有值,使用严格相等运算符(===)来进行判断,只有当数组成员严格等于 undefined,认值才会生效。所以第三个 b 使用了认值。

let [a = ] = [null];             // a=null

我们知道 null==undefined 返回的是 true,null===undefined 返回的是 false。所以数组成员是 null,认值就不会生效。

在 ES6 之前如果我们想交换两个变量的值时,我们需要借助中值来过渡,下面是要交换 a、b 值的过程:

var a = ;
var b = ;
var m = a;
a = b;
b = m // a=4, b=1

在交换 a、b 值时,需要借助中变量来中转,使用 ES6 解构赋值就很简单:

var a = ;
var b = ;
[a, b] = [b, a] // a=4, b=1

在解构数组时,可以忽略不需要解构的值,可以使用逗号对解构的数组进行忽略操作,这样就不需要声明更多的变量去存值了:

var [a, , , b] = [, , , ];
console.log(a);   // 10
console.log(b);   // 40

上面的例子中,在 a、b 中间用逗号隔开了两个值,这里怎么判断间隔几个值呢,可以看出逗号之间组成了多少间隔,就是间隔了多少个值。如果取值很少的情况下可以使用下标索引的方式来值。

通常情况下,需要把剩余的数组项作为单独的数组,这个时候我们可以借助展开语法把剩下的数组中的值,作为单独的数组,如下:

var [a, b, ...rest] = [, , , , ];
console.log(a);     // 10
console.log(b);     // 20
console.log(rest);  // [30, 40, 50]

在 rest 的后面不能有 逗号 不然会报错,程序会认出你后面还有值。...rest 是剩余参数的解构,所以只能放在数组的最后,在它之后不能再有变量,否则则会报错。

对象的解构和数组基本类似,对象解构的变量是在 {} 中定义的。对象没有索引,但对象有更明确的键,通过键可以很方便地去对象中取值。在 ES6 之前直接使用键取值已经很方便了:

var obj = { name: 'imooc', age:  };
var name = obj.name;  // imooc
var age = obj.age;    // 7

但是在 ES6 中通过解构的方式,更加简洁地对取值做了简化,不需要通过点操作额外的取值操作。

var obj = { name: 'imooc', age:  };
var { name, age } = obj;  // name: imooc, age: 7

{} 直接声明 name 和 age 用逗号隔开即可得到目标对象上的值,完成声明赋值操作。

对象的认值和数组的认值一样,只能通过严格相等运算符(===)来进行判断,只有当对象的值严格等于 undefined,认值才会生效。

var {a = , b = } = {a: };                 // a = 3, b = 5
var {a = , b = } = {a: , b: undefined};   // a = 3, b = 5
var {a = , b = } = {a: , b: null};        // a = 3, b = null

所以这里的第二项 b 的值是认值,第三项的 null === undefined 的值为 false,所以 b 的值为 null。

在对象解构出来的变量不是我们想要的变量命名,这时我们需要对它进行。

var {a:x = , b:y = } = {a: };

console.log(x); // 2
console.log(y); // 3

这里把 a 和 b 的变量名重新命名为 x 和 y。

在对象的解构中也可以使用剩余参数,对对象中没有解构的剩余做聚合操作,新的对象。

var {a, c, ...rest} = {a: , b: , c: , d: }
console.log(a);     // 1
console.log(c);     // 3
console.log(rest);  // { b: 2, d: 4 }

对象中的 b、d 没有被解构,通过剩余参数语法把没有解构的对象聚合到一起形成新的对象。

当然字符串也是可以被解构的,字符串可以当作数组被解构。

const [a, b, c, d, e] = 'imooc';
console.log(a);   // "i"
console.log(b);   // "m"
console.log(c);   // "o"
console.log(d);   // "o"
console.log(e);   // "c"

字符串可以被看成类数组的东西,类似数组的对象都有 length ,字符串也可以被当作对象来解构,但是由于字符串只有 length ,所以只能解构出 length 的值。

let {length : len} = 'hello';
console.log(len); // 5

了解了数组和对象的解构,下面我们看下对于复杂数据解构应该如何去解构呢?看下面的例子:

var data = {
  a: ,
  arr: [
    {
      b: ,
      c: 
    }
  ]
}

var { 
  a: newA,
  arr: [
    {
      b: newB
    }
  ]
} = data;
console.log(newA, newB) // 1, 2

上面的例子中 data 的数据解构还算是比较复杂的,对于解构这种既有对象又有数组的数据解构,我们要先声明和目标对象有着相同的数据嵌套,才能去拆解目标对象。这里解构的是 data 中的 a 和 b 的值,而且把 a 和 b 为 newA 和 newB。

本节讲解了 ES6 解构赋值的使用,总结下来一共有以下几点:


联系我
置顶