「スプレッド演算子」という表現を使わない

JavaScript の文脈で ... を「スプレッド演算子」としている記述を見かけます。しかし、それはおそらく不適切で、そもそも ... は JavaScript の演算子ではないでしょう、というまとめです。

まとめ

... を使う場面は以下の4つです。

  1. Array リテラル array = [...foo, ...bar]
  2. Object リテラル object = {...foo, ...bar}
  3. 関数呼び出し foo(...bar)
  4. 引数の名前付け function foo(bar, ...baz) {}
  5. iterable の分割代入 const [foo, ...bar] = iterable 1
  6. Object の分割代入 const {foo, ...bar} = object 1

MDN の wiki は、はじめの3つを spread syntax、4. を rest syntax または rest parameters としています。
... は JavaScript の演算子ではありませんから、これをスプレッド「演算子」と呼ぶのはやめましょう。
特に後半は複数の値をまとめていて、動きとしてはスプレッド(展開)と逆ですから「スプレッド」の部分も正しくないです。

spread-rest.png

... は演算子ではない

演算子

演算子は関数のように、1つ以上の値から1つの値を作ります。-123-123 から -123 を作ります。1 + 2+12 から 3 を作ります。

...foo は評価できない

... が演算子だとすると、......foo のように使いますから、単項演算子ということになります。しかし、[...foo]{...foo} は値になりますが、...foo は値になりません。... を演算子と呼べない気がします。

See the Pen eval ...foo by hoo (@hoo-chan) on CodePen.

単項演算子の種類

https://tc39.github.io/ecma262/#sec-unary-operators
によれば、単項演算子は、以下の9つです。

  1. ++
  2. --
  3. delete
  4. void
  5. typeof
  6. +
  7. -
  8. ~
  9. !

ここに ... はありません。

AST だと何になっているか?

[...foo](...foo)=>{} を分解すると、以下のようになります。それぞれ、SpreadElementRestElement になっています。これらは式の構成要素であって、それ単体で式としては評価できません。

See the Pen acorn.parse by hoo (@hoo-chan) on CodePen.

まとめ

... は演算子ではなくて、構文の一部として考えるべきでしょう。


  1. 2018/3/23 に追記しました。@mysticatea さんコメントありがとうございました。 

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.