ES6之赋值解构

102 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情  1b1882ba6eb785818e96e5c7263b28e.jpg

前言

es6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。其中解构赋值又可以分成数组解构、对象解构、字符串解构。

1、数组的解构

对变量的赋值遵循一个规则,只要左右两边的模式相同,就可以进行合法赋值

1.1 简单使用

   const STAR = ['小沈阳', '刘能', '赵四', '宋小宝'];
   let [xiao, liu, zhao, song] = STAR;
   console.log(xiao,liu,zhao,song); //输出: '小沈阳','刘能', '赵四', '宋小宝'

1.2 一一比对,如没有对应的值,变量值等于undefined

一一对应

   // 例1:
   let [ foo, [[bar], baz ]] = [ 1, [[2], 3 ]];
   console.log(foo, bar, baz); // 输出: 1 2 3
   console.log(foo, [[bar], baz]); // 输出:1 [[2], 3]
   
   // 例2:
   let [ , , third] = ["foo", "bar", "baz"];
   console.log(third); // 输出:baz

不完全解构

   let [ bar, foo ] = [1];
   console.log(bar, foo); // 输出: 1 undefined

ps:foo 位置对应没有值,所以是undefined

1.3 可以设置指定默认值,默认值也可以是一个合法的变量

   let [foo = true] = [];
   console.log(foo); // 输出:true

1.4 使用扩展运算符(...)

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

1.5 如果等号的右边不是数组(不是可遍历的结构),那么将会报错

   let [foo] = 1;
   let [foo] = false;
   let [foo] = NaN;
   let [foo] = undefined;
   let [foo] = null;
   let [foo] = {};
   // 报错

2、对象的解构

与数组的解构有一个很大的区别:对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

2.1 简单使用

   const STAR  = {
       name: "赵本山",
       age: "不详",
       xiaopin: function () {
          console.log("演小品");
       }
   }
   let { name, age, xiaopin, sex } = STAR;
   console.log(name, age, xiaopin, sex);
  // 输出: 赵本山 不详 f(){ console.log("演小品") }  underfined

ps: 方法同样可以被解构,而 sex 在对象 STAR 是没有的,所以是 underfined

2.2 自定义变量名或方法名

   const OBJ = {
       name: "孙悟空"
   }
   const { name: monicker } = OBJ;
   console.log(name); // 报错: name is not defined
   console.log(monicker); // 输出: 孙悟空
   
   const { log: minelog } = console;
   log('fun'); // 报错:  log is not defined
   minelog('fun'); // 输出: fun

ps: 如果想要自定义变量名和方法名,要用 : 的方式,其中 : 前面的属性就失效了

2.3 使用扩展运算符(...)

   let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }
  console.log(x, y, z); // 输出 1, 2, { a: 3, b: 4 }

2.4 层层解构

   const node = {
      loc: {
        start: {
          line: 1,
          column: 5
        }
      }
    }
 
    let { loc, loc: { start }, loc: { start: { line }} } = node;
    console.log(line); // 输出:1
    console.log(loc); // 输出:{ start: { line: 1, column: 5} }
    console.log(start); // 输出: { line: 1, column: 5} 

ps: loc: { start: { line }} 中,只有 line 是变量,所以是1

2.5 数组也是一个特殊的对象

   let arr = ['a', 'b', 'c'];
   let {0 : first, [arr.length - 1] : last} = arr;
   console.log(first, last);  // 输出: a c

2.6 设置默认值,生效条件是对象的属性值严格等于 undefined

   let {x, y = 5} = {x: 1};
   console.log(x, y); // 输出:1 5
    
   let {x = 3} = {x: undefined}; // 输出:3
   let {x = 3} = {x: null}; // null

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

3、字符串解构

字符串可以当作数组解构

   const [a, b, c, d, e] = '字符串解构';
   console.log(a, b, c, d, e);  // 输出: 字 符 串 解 构

字符串可以当作数组解构

   const { length } = '字符串解构';
   console.log(length);  // 输出: 5

4、使用场景

4.1 使用解构做函数的参数

   // 数组
   function add ([x, y]) {
       return x + y;
   }
   console.log(add([1, 2])); // 输出:3
   
   // 对象
   function subtract ({ x, y }) {
       return x - y;
   }
   console.log(subtract({ x: 3, y: 1 })); // 输出:2

4.2 使用解构交换变量

   let x = 10;
   let y = 20;
   [x, y] = [y, x];
   console.log(x, y); // 输出:20 10

4.3 使用解构返回多个值

   function example() {
       return {
           x: 10,
           y: 20
       };
   }
   let { x, y } = example();
   console.log(x, y); // 输出: 10 20

4.4 遍历Map结构

   let map = new Map();
   map.set('first', 'hello');
   map.set('second', 'world');

   for (let [key, value] of map) {
     console.log(key + " is " + value);
   }