解构赋值是 ES6 引入的一个很棒的特性。解构是 JavaScript 中将数组中的值或对象中的属性解压缩为不同的变量的方式。也就是说,我们可以从数组和对象中提取数据并将其赋值给变量。

为什么这是必要的?

假设我们要从数组中提取数据,以前我们是怎么操作的?

let introduction = ["Hello", "I" , "am", "Sarah"];
let greeting = introduction[0];
let name = introduction[3];

console.log(greeting);//"Hello"
console.log(name);//"Sarah"

可以看到,当我们想从数组中提取数据时,必须一遍又一遍地做同样的事情。

ES6 的解构赋值使提取数据变得更加容易。怎么做呢?首先,我们将讨论数组的解构赋值。然后,我们将进行对象解构。

让我们开始吧。

基本的数组解构

如果我们要从数组中提取数据,那么使用解构分配非常简单。

参考第一个数组示例,与其采用重复的过程,我们这么做:

let introduction = ["Hello", "I" , "am", "Sarah"];
let [greeting, pronoun] = introduction;

console.log(greeting);//"Hello"
console.log(pronoun);//"I"

这么做也会有相同的结果。

let [greeting, pronoun] = ["Hello", "I" , "am", "Sarah"];

console.log(greeting);//"Hello"
console.log(pronoun);//"I"

在赋值之前声明变量

可以在赋值之前像这样声明变量:


let greeting, pronoun;
[greeting, pronoun] = ["Hello", "I" , "am", "Sarah"];

console.log(greeting);//"Hello"
console.log(pronoun);//"I"

请注意,变量是从左到右设置的。因此,第一个变量获取数组中的第一项,第二个变量获取数组中的第二个变量,依次类推。

跳过数组中的项目

如果我们想获取数组中的第一项和最后一项,而不是第一项和第二项,并且只想分配两个变量,该怎么办? 这也可以实现。看下面的例子:

let [greeting,,,name] = ["Hello", "I" , "am", "Sarah"];

console.log(greeting);//"Hello"
console.log(name);//"Sarah"

刚才发生了什么?

查看变量赋值左侧的数组。请注意,我们有三个逗号,而不只是一个。逗号分隔符用于跳过数组中的值。因此,如果要跳过数组中的项目,只需使用逗号即可。

我们再试一次,跳过列表中的第一项和第三项。

let [,pronoun,,name] = ["Hello", "I" , "am", "Sarah"];

console.log(pronoun);//"I"
console.log(name);//"Sarah"

因此,逗号分隔符起到了神奇的作用。如果我们要跳过所有项目,则只需执行以下操作:

let [,,,,] = ["Hello", "I" , "am", "Sarah"];

赋值数组的其余部分

如果我们想将数组中的某些项赋值给一些变量,而将数组中的其余项分配给一个特定的变量,该怎么做呢?在这种情况下,我们可以这样做:

let [greeting,...intro] = ["Hello", "I" , "am", "Sarah"];

console.log(greeting);//"Hello"
console.log(intro);//["I", "am", "Sarah"]

使用这个模式,你可以解压缩数组,并将数组的其余项分配给一个变量。

用函数解构赋值

我们还可以从函数返回的数组中提取数据。假设我们有一个返回数组的函数,如下所示:

function getArray() {
    return ["Hello", "I" , "am", "Sarah"];
} 
let [greeting,pronoun] = getArray();

console.log(greeting);//"Hello"
console.log(pronoun);//"I"

我们得到相同的结果。

使用默认值

可以为变量分配默认值,以防止从数组中提取的值是 undefined

let [greeting = "hi",name = "Sarah"] = ["hello"];

console.log(greeting);//"Hello"
console.log(name);//"Sarah"

name 的值就是 “Sarah”,因为它在数组中未定义。

使用解构赋值交换值

此外,我们可以使用解构赋值来交换变量的值:

let a = 3;
let b = 6;

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

console.log(a);//6
console.log(b);//3

接下来,我们讨论对象解构。

对象解构

首先,让我们看看为什么需要对象解构。

假设我们要从对象中提取数据并赋值给新变量,在 ES6之前,是怎么做的呢?

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let name = person.name;
let country = person.country;
let job = person.job;

console.log(name);//"Sarah"
console.log(country);//"Nigeria"
console.log(job);//Developer"

提取所有数据是很繁琐的,我们必须重复做同样的事情。ES6 的解构确实可以帮我们节省很多时间。

基本的对象解构

让我们用 ES6 重复上面的示例。不用一一赋值,我们可以使用左侧的对象提取数据:

    
let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let {name, country, job} = person;

console.log(name);//"Sarah"
console.log(country);//"Nigeria"
console.log(job);//Developer"

你将获得相同的结果。将变量分配给尚未声明的对象也是有效的:

let {name, country, job} = {name: "Sarah", country: "Nigeria", job: "Developer"};

console.log(name);//"Sarah"
console.log(country);//"Nigeria"
console.log(job);//Developer"

在分配之前声明的变量

对象中的变量可以在使用解构分配之前声明。让我们尝试一下:

let person = {name: "Sarah", country: "Nigeria", job: "Developer"}; 
let name, country, job;

{name, country, job} = person;

console.log(name);// Error : "Unexpected token ="

等等,发生了什么事?哦,我们忘了在大括号前加上()

使用不带声明的对象文字解构赋值时,在赋值语句外面加上 ( ) 是必需的语法。这是因为左侧的 {}  被认为是一个块,而不是对象文字。因此,这是正确执行此操作的方法:

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};
let name, country, job;

({name, country, job} = person);

console.log(name);//"Sarah"
console.log(job);//"Developer"

在使用这个语法时还需要注意,() 之后应使用分号。否则,它可能被用来执行上一行的代码。

请注意,对象左侧的变量应与对象 person 中的属性键具有相同的名称。如果名称不同,将显示 undefined

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let {name, friends, job} = person;

console.log(name);//"Sarah"
console.log(friends);//undefined

但是,如果我们要使用新的变量名,也是可以的。

使用一个新的变量名

如果要将对象的值分配给新变量,而不是使用属性名称,则可以执行以下操作:

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let {name: foo, job: bar} = person;

console.log(foo);//"Sarah"
console.log(bar);//"Developer"

提取的值被传递给新的变量 foobar

使用默认值

对象解构中也可以使用默认值,以防止要从对象中提取数据时,变量是 undefined

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let {name = "myName", friend = "Annie"} = person;

console.log(name);//"Sarah"
console.log(friend);//"Annie"

因此,如果该值不是未定义的,则该变量将存储从对象中提取的值(例如 name)。否则,它将使用默认值,就像 friend 一样。

当我们将值分配给新变量时,还可以设置默认值:

let person = {name: "Sarah", country: "Nigeria", job: "Developer"};

let {name:foo = "myName", friend: bar = "Annie"} = person;

console.log(foo);//"Sarah"
console.log(bar);//"Annie"

以上代码是从 person 中提取了 name,并将其分配给了另一个变量。friendperson 中是 undefined,因此新变量 bar 被赋予默认值。

计算属性名称

计算属性名称是另一个对象特性,也可用于解构。如果将属性放在方括号中,则可以通过表达式指定属性的名称:

let prop = "name";

let {[prop] : foo} = {name: "Sarah", country: "Nigeria", job: "Developer"};

console.log(foo);//"Sarah"

结合数组和对象

数组也可以与对象一起使用,以进行对象解构。

let person = {name: "Sarah", country: "Nigeria", friends: ["Annie", "Becky"]};

let {name:foo, friends: bar} = person;

console.log(foo);//"Sarah"
console.log(bar);//["Annie", "Becky"]

对象解构中的嵌套

在解构的时候,也可以嵌套对象:

let person = {
    name: "Sarah",
    place: {
        country: "Nigeria", 
        city: "Lagos" }, 
    friends : ["Annie", "Becky"]
};

let {name:foo,
     place: {
         country : bar,
         city : x}
    } = person;

console.log(foo);//"Sarah"
console.log(bar);//"Nigeria"

对象解构中的 rest 语法

在解构时未分配的属性键,可以通过 rest 语法将这些键和它们的值复制成一个新的对象:

let person = {name: "Sarah", country: "Nigeria", job: "Developer" friends: ["Annie", "Becky"]};

let {name, friends, ...others} = person;

console.log(name);//"Sarah"
console.log(friends);//["Annie", "Becky"]
console.log(others);// {country: "Nigeria", job: "Developer"}

在这里,其键不能和罗列出的变量名对应的其余属性被分配给变量 others。这里的 rest 语法是 ...others...others 可以被命名为任意的变量。

最后一件事——让我们看看如何在函数中使用对象解构。

对象解构和函数

对象解构可用于为函数分配参数:

function person({name: x, job: y} = {}) {
    console.log(x);
}

person({name: "Michelle"});//"Michelle"
person();//undefined
person(friend);//Error : friend is not defined

注意参数对象右侧的 {},这使我们可以在不传递任何参数的情况下调用该函数。这就是得到 undefined 结果的原因。如果我们将其删除,则会收到错误消息。

我们还可以为参数分配默认值:

function person({name: x = "Sarah", job: y = "Developer"} = {}) {
    console.log(x);
}

person({name});//"Sarah"

正如我们在上面的示例中看到的,我们可以使用数组和对象解构来做很多事情。

谢谢阅读:)

原文:How to Use Array and Object Destructuring in JavaScript,作者:Sarah Chima Atuonwu