JavaScript 中 Spread 运算符的用处
作者 William Le
介绍
spread 运算符是 ES6 引入 JavaScript 的一项功能, 使您可以访问可迭代对象的内部 。这里的“可迭代对象”指的是是可逐项迭代的任何对象,比如数组、对象文字和字符串。我们可以用某种顺序方式遍历这些类型 JavaScript 。 例如,可以在数组上使用 for
循环 ,也可以在 JavaScript 对象中使用 for...in
循环。
关于Spread 运算符的基本知识
spread 运算符使您可以访问这些可迭代对象内部的所有项。示例如下:
const foo = [
'hello',
'bonjour',
'konnichiwa'
];
const bar = [...foo]; // 三个点“...”是 spread 操作符的语法。
console.log(bar);
在控制台中运行后,输出如下:
['hello', 'bonjour', 'konnichiwa'];
变量 bar
从 变量 foo
得到了一个精确的副本,spread 运算符实际上是“挖出”了 foo
数组的内部内容,并且将这些值分布在 bar
的新数组中。
请着重注意 spread操作符 [...foo]
的一组括号 [] 。spread 操作符将这些值分布到一个和原对象类型相同的新对象中。在以下示例中,试着在数组字面中运行不带括号 [] 的代码:
const foo = [
'hello',
'bonjour',
'konnichiwa'
];
const bar = ...foo;
console.log(bar);
输出:
Uncaught SyntaxError: expected expression, got '...'
我们已经对 spread 运算符有了基本的认识,下面一起来了解它的一些常见用途。
复制可迭代对象
正如前文所介绍的那样,spread 运算符是复制可迭代对象的最佳方法之一。有许多更复杂的方法可以执行此操作,而 spread 操作符的简洁性使得操作过程十分轻松。
const foo = {
english: 'hello',
french: 'bonjour',
japanese: 'konnichiwa'
};
const bar = {...foo};
console.log(bar);
输出如下:
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa' }
合并可迭代对象
我们还可以使用 spread 运算符来将几个可迭代对象组合成一个可迭代对象。
const foo = ['hello', 'bonjour', 'konnichiwa'];
const bar = ['gutentag', 'saluton'];
const baz = [...foo, ...bar];
console.log(baz);
此操作会输出 foo
和 bar
的内容,而它们共同组成了 baz
。
输出:
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'saluton']
您还可以将已展开的数组放置在另一个数组中:
const foo = ['hello', 'bonjour', 'konnichiwa'];
const bar = [...foo, 'gutentag', 'saluton'];
console.log(bar);
现在, bar
就在 foo
的基础上多包含了几项内容。
输出:
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'saluton']
您可以这样理解,spread 运算符仅仅是保留可迭代对象中的项,而非对象本身。
合并对象文字的过程与合并数组类似:
const foo = {
english: 'hello',
french: 'bonjour',
japanese: 'konnichiwa'
};
const bar = {
german: 'gutentag',
esperanto: 'saluton'
};
const baz = {...foo, ...bar};
console.log(baz);
两个对象的 spread 运算符包含各自对象的内容,因此能够保证它们在新对象中合并时仍然包含这些内容。 输出:
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton' }
Object.assign()
能够实现这一任务,但相比之下,spread 的句法更加简洁。
注意:虽然您可以使用 spread 操作符合并不同类型的可迭代对象,但这样可能会导致一些不必要的行为。对于数组和字符串这样的对象,您可以把数组中的项或字母索引(例如: {0: 'a', 1: 'b', 2: 'c'} 看做对象的键。如果您在对象文字中对数组或字符串使用 spread 运算符,那么结果将包含这些键/值对。然而,由于对象的键不是数字,您并不能在数组中使用它们的值。
如果出现重复键时会怎么样呢?
const foo = {
english: 'hello',
french: 'bonjour',
japanese: 'konnichiwa'
};
const bar = {
english: 'howdy',
german: 'gutentag'
};
const baz = {
...foo,
...bar,
esperanto: 'saluton',
korean: 'annyeong'
};
console.log(baz);
如上,我们将两个对象合并成一个新的对象时,发现两个对象都包含 english 条目。 输出:
{ english: 'howdy', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton', korean: 'annyeong' }
重复的键会按照出现顺序被覆盖。请注意,在使用 spread 运算符合并对象文字时,务必要考虑重要数据在此操作过程中丢失的可能性。
将实参输入函数
在应用 apply
方法(该方法可将变量值提供给函数)的很多场合中,也可以使用 spread 运算符,原理是类似的:
function calcVolume(width, height, depth) {
return width * height * depth;
};
calcVolume(12, 30, 14); // 基础
// 将实参从一个变量输入到函数中
const cube = [12, 30, 14];
calcVolume.apply(null, cube); // 使用“apply”
calcVolume(...cube); // 使用spread 运算符
当 apply
并不能完全适用时,spread 运算符能使将一系列实参输入函数的操作过程变得异常容易。
在字符串中使用 spread 运算符
最后,您还可以在字符串中使用 spread 运算符,因为它们也被视为可迭代对象。
const foo = "jumanji";
const bar = [...foo];
console.log(bar);
以上操作将字符串 jumanji 拆分为多个单独字符。 输出:
// [ "j", "u", "m", "a", "n", "j", "i" ]
小结
spread 运算符是一项非常受欢迎的功能,除了今天介绍的 ES6 ,它也在包括 C ++ 和 Python 在内的其他语言中提供。使用它可以更轻松地实现一些常见的编程任务,而本指南也帮助您掌握了一些实际的使用方法。如果想了解更多此类内容,请持续关注我们。