Introduction

The spread operator is a feature of JavaScript introduced with ES6 that gives you access to the insides of an iterable object. An “iterable object” is anything you can iterate over item by item, such as arrays, objects literals, and strings. These kinds of JavaScript types can be traversed in some sequential fashion. For example, you can use a for loop on an array, or with JavaScript objects, you can use for…in loops.

The Basics of the Spread Operator

The spread operator effectively gives you access to all of the items inside these iterable objects. それが何を意味するかを説明するために例を見てみましょう:

const foo = [
  'hello',
  'bonjour',
  'konnichiwa'
];
const bar = [...foo];  // the three dots "..." are the spread operator syntax.

console.log(bar);

Running this in the console should print the following:

Output
['hello', 'bonjour', 'konnichiwa'];

変数 bar wound up an exact copy of the variable foo. The spread operator essentially ‘scooped’ out the insides of the foo array and spread the values across the new array in bar.

It’s important to note the brackets around the spread operator, [...foo]. The spread operator spreads these values within a new object of the same type; in this case, an array literal. Try running the code without the brackets:

const foo = [
  'hello',
  'bonjour',
  'konnichiwa'
];
const bar = ...foo;

console.log(bar);
Output
Uncaught SyntaxError: expected expression, got '...'

基本的な考え方がわかったので、スプレッド演算子が役立つ可能性のある一般的なタスクを見てみましょう。

反復可能なオブジェクトの複製

前に見たように、スプレッド演算子は反復可能なオブジェクトを複製するための最良の方法の1つです。 There are more complex ways to do this, but the conciseness of the spread operator makes it delightfully easy. Using the spread operator to duplicate object literals isn’t much different than for arrays. For example:

const foo = {
  english: 'hello',
  french: 'bonjour',
  japanese: 'konnichiwa'
};
const bar = {...foo};
console.log(bar);

This leads to the following:

Output
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa' }

反復可能なオブジェクトのマージ

The spread operator can also be used to compose a single iterable object from several others.

const foo = ['hello', 'bonjour', 'konnichiwa'];
const bar = ['gutentag', 'saluton'];
const baz = [...foo, ...bar];

console.log(baz);

This will output the contents of foobar which are now contained in baz:

Output
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'saluton']

You can also place a spreaded array inside another array as you would any other item:

const foo = ['hello', 'bonjour', 'konnichiwa'];
const bar = [...foo, 'gutentag', 'saluton'];

console.log(bar);

bar contains some additions to foo:

Output
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'hello-ey']

A good way to think about it is that the spread operator just holds the items within the iterable object, rather the objects themselves.

オブジェクトリテラルはどうですか? これは、配列のマージと非常によく似ています。

const foo = {
  english: 'hello',
  french: 'bonjour',
  japanese: 'konnichiwa'
};
const bar = {
  german: 'gutentag',
  esperanto: 'saluton'
};
const baz = {...foo, ...bar};

console.log(baz);

As the spread operator for the two objects contains those objects’ internals, using them in the context of a new object literal will ensure that they have those contents as well.

Output
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton' }

This is a common task for Object.assign() but the spread syntax makes this far more concise.

Note: While you can merge iterable objects of different types using the spread operator, this may lead to some unwanted behaviors. For arrays and strings, you can think of them as objects where the keys are item or letter’s index in the array (e.g: {0: 'a', 1: 'b', 2: 'c'}. Should you use the spread operator for an array or string in the context of an object literal, your results will contain these key/value pairs. However, since objects have keys that are not numbers, you will not be able to use their values in an array context.

What happens when there are duplicate keys?

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

Here, we’re merging two existing objects into a third, both of which contain an entry for english.

Output
{ english: 'howdy', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton', korean: 'annyeong' }

The duplicate keys are overwritten in the order they’re applied. It’s important to take into consideration whether or not valuable data will be lost in the process of using the spread operator to merge iterable objects.

関数への引数のフィード

The spread operator can be used in many instances where one might choose to use the apply method, which passes the values of a variable to a function in a similar way.

function calcVolume(width, height, depth) {
  return width * height * depth;
};

calcVolume(12, 30, 14);  // basic

// Passing arguments to the function from a variable:
const cube = [12, 30, 14];
calcVolume.apply(null, cube);  // using "apply"
calcVolume(...cube);     // using "spread operator"

The spread operator makes it easy to feed a series of arguments into functions in cases where apply may not be totally applicable.

Using the Spread Operator With Strings

Lastly, you can also use the spread operator with strings since they’re also considered an iterable object.

const foo = "jumanji";
const bar = [...foo];

console.log(bar);

This will break the string jumanji up into its individual characters.

Output
// [ "j", "u", "m", "a", "n", "j", "i" ]

結論

The spread operator was a highly requested feature from several other languages like C++ and Python, and now it’s here in ES6! It makes some common programming tasks much easier to do, and with this tutorial, you learned practical ways you could use it. For more information on the spread operator, MDN has in-depth documentation available.