JS 解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,被称为解构赋值。这种写法属于“模式匹配”。这种方式的出现大大提高了代码的扩展性。

数组解构

从数组中提取值,按照对应位置,对变量赋值。匹配采用模式匹配,匹配的到就获取值,匹配不到就是 undefined。

我们来看这段代码,这就是数组解构的简单使用,等号左侧的数组字面量中的每个变量名称映射为右侧数组的相同位置的元素。

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

等价于下面的代码

let a = 1;
let a = 2;
let a = 3;

默认值

解构语法允许我们设置默认值,当我们解构后的值为 undefined 时,默认值就会被赋给该变量。

let [a = 0, b = 1] = [3];
console.log(a)//3
console.log(b)//1

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

// 结构的值为 null
let [c = 0] = [null];
console.log(c)//null

默认值是惰性求值,如果默认值是一个表达式,并且解构的值不为 undefined,那么该表达式不会被求值。

function test() {
  console.log('执行');
  return 0;
}
let [c = test()] = [null];
console.log(c)//null

忽略值

当我们只想拿到数组里部分值时,可以忽略不想要的值。

let [a = 0, , b = 1] = [2, 3, 4];
console.log(a)//2
console.log(b)//4

收集剩余值

若只想拿到数组中某一项的值,又不想丢掉后边的值可以这样做。

let [a, ...b] = [2, 3, 4];
console.log(a)//2
console.log(b)//[3,4]

嵌套数组解构

可以看到下面的数组结构的结构的结果与‘收集剩余值’的结果一样。

let [a, b] = [2, [3, 4]];
console.log(a)//2
console.log(b)//[3,4]

下面的代码是准确的拿到每一项的值,因为

let [a, [b, c]] = [2, [3, 4]];
console.log(a)//2
console.log(b)//3
console.log(c)//4

字符串解构

在数组解构中,解构的目标若为可遍历对象,皆可进行解构赋值,可遍历对象即实现Iterator 接口的数据。

let myName = '孤城浪人';
let [n, a, m, e] = myName;
console.log(n)//孤
console.log(a)//城
console.log(m)//浪
console.log(e)//人

// 也可以使用扩展操作符
let [b, ...c] = myName;
console.log(b)//孤
console.log(c)//['城', '浪', '人']

对象解构

对象解构跟数组解构很相似。唯一需要注意的是数组必须要位置一致,而对象则必须要属性名一致才能解构成功

// 简单使用
let obj = {
  name: '孤城浪人',
  age: 18
}
let { name, age } = obj;
console.log(name);//孤城浪人
console.log(age);//18

赋值给新变量名

如果原对象的属性名太长,在解构的时候可以给该属性重命名,规则{原属性名:新属性名}

let obj = {
  name: '孤城浪人',
  age: 18
}
let { name: a, age: b } = obj;
console.log(a);//孤城浪人
console.log(b);//18

默认值

对象解构依然可以给默认值。下面的代码中 obj 对象中没有 nam 属性,所以它的值就是默认值。

let obj = {
  name: '孤城浪人',
  age: 18
}
let { nam = '孤城', age = 22 } = obj;
console.log(nam);//孤城浪人
console.log(age);//18

收集剩余值

对象也可以使用扩展操作符来搜集剩余的值。

let obj = {
  name: '孤城浪人',
  age: 18,
  sex: 'man'
}
let { name = '孤城', ...obj1 } = obj;
console.log(name);//孤城浪人
console.log(obj1);//{age: 18, sex: 'man'}

复杂对象解构

有时会遇到复杂对象(嵌套对象、数组)的解构情况,如下面的代码所示。

let people = {
    name: 'super',
    age: 18,
    like: ['篮球', '羽毛球'],
    history: [
        { name: 'mvp' },
        { name: 'cba' },
        { name: 'm' }
    ]
};
let {like, history: [first, second, third] } = people;
console.log(like); // ['篮球', '羽毛球']
console.log(first); // {name: 'mvp'}

应用

解构函数参数

无非就是函数的参数是对象或者数组,规则和解构对象或数组一致。

let obj = {
  name: '孤城浪人',
  age: 18
}
function test({ name, age }) {
  console.log(name, age); // 孤城浪人 18
}
test(obj);

解构函数返回值

当时函数的返回值是一个对象或则数组时依然可以解构。

function test() {
  let obj = {
    name: '孤城浪人',
    age: 18
  }
  return obj;
}
let { name, age } = test(obj);
console.log(name, age); // 孤城浪人 18

交换两个变量的值

以前想要交换两个变量的值必须要有一个中间变量暂时保存其中一个变量的值。如下代码

let a = 1, b = 2;
let c = a;
a = b;
b = c;

但是有了解构赋值就不需要了,一行代码搞定。

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