解构赋值是 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"
提取的值被传递给新的变量 foo
和 bar
。
使用默认值
对象解构中也可以使用默认值,以防止要从对象中提取数据时,变量是 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
,并将其分配给了另一个变量。friend
在 person
中是 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