ES6_解构赋值

537 阅读3分钟

解构(Destructuring)

什么是解构?

使用ES6的一种语法规则,将一个对象或数组的某个属性提取到某个变量中

解构不会对被解构的目标造成任何影响

一、数组解构

如果解构不成功,变量的值就为undefined

等号右边的值只要具有Iterator接口,都可以采用数组形式的解构赋值。

1. 使用默认值

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

let [x = 1] = [undefined];
// x = 1;

let [x = 1] = [null];
// x = null;

2. 嵌套解构

let [foo, [[bar], baz]] = [1, [[2], 3]];
// foo = 1
// bar = 2
// baz = 3

let arr = [1, 2, 3, {name: 'gyq'}];
let [,,,{name: oName}] = arr;
// oName = 'gyq'

3. 用对象来解构数组

数组本质上也是对象,因此可以对数组进行对象属性的解构

let arr = [1, 2, 3];
let {0: first, 2: last} = arr;
// first = 1  last = 3

let {legnth} = arr;
// length = 3

二、对象解构

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的。变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值。

1. 在解构中使用默认值

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

let {x = 3} = {};
// x = 3

2. 非同名属性解构

let {foo: baz} = {foo: 'gyq'}
// baz = 'gyq'

上面的代码,foo是匹配模式,baz才是变量,真正被赋值的是变量

实际上,对象的解构赋值是下面形式的简写:

let {foo: foo, bar: bar} = {foo: 'gyq', bar: 'gy'};

也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。

3. 默认值和非同名属性解构同时使用

let {foo: bar = 10} = {}
// bar = 10

4. 嵌套

const user = {
    name: 'gyq',
    age: 18,
    sex: 'male',
    address: {
        province: 'jiangsu',
        city: 'nanjing'
    }
}
const {name, address: {province}} = user;
// name = 'gyq', province = 'jiangsu'

5. 特殊

如果要将一个已经声明的变量用于解构赋值,必须非常小心

// 错误写法
let x;
{x} = {x: 1};
// 上面的写法报错,因为JS引擎会将{x}理解为一个代码块,从而发生语法错误。
// 只有不将大括号写在行首,避免JS将其理解为代码块就可以。

// 正确的写法
let x;
({x} = {x: 1});

三、字符串、数值、boolean解构赋值

字符串、数值、boolean都可以进行解构

解构赋值的规则是,只要等号右边的值不是对象和数组,就先将其转为对象。由于undefined和null无法转为对象,所有对它们进行解构赋值时都会报错。

四、函数参数解构赋值

理解下面的两种不同,使用的时候也要注意:

function move({x = 0, y = 0} = {}) {
    return [x, y];
}
move({x: 3, y: 8});     // [3, 8]
move({x: 3});           // [3, 0]
move({{}});             // [0, 0]
move();                 // [0, 0];
// 上面的代码,函数的参是是一个对象,通过对这个对象进行解构,得到变量x和y的值。
// 如果解构失败,x和y等于默认值。

function move({x, y} = {x: 0, y: 0}) {
    return [x, y];
}
move({x: 3, y: 8});     // [3, 8]
move({x: 3});           // [3, undefined];
move({});               // [undefined, undefined];
move();                 // [0, 0]
// 上面的代码是为函数的参数指定默认值,而不是为变量x和y指定默认值

五、用途

  • 交换变量的值
  • 从函数返回多个值
  • 函数参数的定义
  • 提取JSON数据
  • 函数参数的默认值
  • 遍历map结构
    for (let [key, value] of map) {
        console.log(key + "is" + value);
    }
    
  • 输入模块的指定方法