Skip to main content

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);

此操作会输出 foobar 的内容,而它们共同组成了 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 在内的其他语言中提供。使用它可以更轻松地实现一些常见的编程任务,而本指南也帮助您掌握了一些实际的使用方法。如果想了解更多此类内容,请持续关注我们。