「…」←これ、ただの省略記号かと思ってました。(Spread operatorのお話)

2016年02月15日

カテゴリー:

【2017.08.04追記】
記事の内容が「Spread operator」と「残余引数 (Rest parameters) 」とが混同しているとのご指摘を受け、内容を一部修正しました。

先日、ES2015の新構文について少し調べていた時の事。ふとこんなサンプルコードが目につきました。

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);}

一見、なんの変哲もない普通のコードかと思っていたのですが、よく見ると関数の引数部分に「…args」というのがあります。

ドット3つ(日本語で言うところの3点リーダ)の後に引数名となっていますね。
私もよくブログ内で記事を書くときに、省略やエトセトラ(etc)的な意味を表現するために「…」を使いますが、上記のコードの「…args」の部分もその類かと思っていました。

が、どうも引っかかる。

「…args」の様に args の前に「…」をわざわざ記述することの必要性がどこにあるのでしょうか?
単純に myFunction(args) で十分じゃないの?

そんなわけで、もしかしたらこの「…」には何か特別な意味があるのでは?と思い、ちょっと調べてみました。
で、以下にしっかりと書いてありました。

Spread operator – JavaScript | MDN

さすがはMDN様。
どうやらSpread operator(スプレッドオペレータ)という、ES2015(ES6)からの新しい演算子ということらしいです。

Spread operator(スプレッドオペレータ)とは

MDNの解説を見ると、Spread operatorについて次の様に書かれています。

spread operatorによって式が(関数の呼び出しのための)複数の引数か(配列リテラルのための)複数の要素が期待される場所で拡張されます。

引用元:Spread operator – JavaScript | MDN

反復可能なオブジェクト(要は配列とか)を、文脈に合わせて展開してくれるようなイメージでしょうか。※もう少し的確&簡潔に説明できれば良いのですが、余計わけ分からなくなってしまったらすみません。

とりあえず、具体的な例を書いた方がイメージしやすいかもしれませんので、いくつかコード書きます。

var arr = [1, 2, 3];

console.log(arr); //[1, 2, 3]
console.log(...arr); //1 2 3
var arr = [1, 2, 3];
var fn = function (a, b, c) {
    return a + b + c;
};

console.log(fn(1, 2, 3)); //6
console.log(fn(...arr)); //6

//ES5の場合(従来の手法)
console.log(fn.apply(null, arr)); //6
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr = [...arr1, ...arr2];

console.log(arr); //[1, 2, 3, 4, 5, 6]

//ES5の場合(従来の手法)
console.log(arr1.concat(arr2)); //[1, 2, 3, 4, 5, 6]

Array.prototype.push.apply(arr1, arr2);
console.log(arr1); //[1, 2, 3, 4, 5, 6]

まとめ

個人的には配列の結合くらいでしか使わない気がします。
コーディングスタイルにもよるかもしれませんが、関数へのパラメータ受け渡しで配列を展開したりするようなケースをあまりイメージ出来ないので。

使いどころによっては便利かもしれませんが、あまり多用するとコードがトリッキーになりすぎ、可読性が損なわれてしまう可能性もありそうなので、ある程度使いどころを限定した方が良いかもしれませんね。
例えば、これまで push や concat を使用していたような箇所では、可読性を損なわずによりスマートなコードに出来るかもしれません。


あ、今までブログ内で省略的な意味で3点リーダ使ってたけど、こりゃ注意しないとな。

参考リンク

ES6構文の … (Spread operator)と { prop } (shorthand property names)について – yutaponのブログ