君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

【突然の沈黙】JavaScriptのobjectスプレッド演算子について

いきさつ

ソースコードを読んでいたら、

var arr = [1, 2, 3]
var arr2 = [4, 5, 6]
arr.push(...arr2)

とつぜん処理の中で沈黙(...)し始めた。

f:id:karoten512:20180511220526j:plain

気持ち悪かったので調べてみた。

ドキュメントを見てみる

スプレッド構文を使うと、関数呼び出しでは 0 個以上の引数として、 Array リテラルでは 0 個以上の要素として、 Object リテラルでは 0 個以上の key-value のペアとして、 Array や String などの iterable オブジェクトをその場で展開します。

うーん。

わかるようなわからんような。

実際に試してみよう。

...Array, ...Stringはどうなるのか

...Array だと

var arr = [1,2,3]
console.log(...arr) // 1 2 3

ばらばらになるイメージ?

...Stringだと

var str = 'hello world'
console.log(...str) // h e l l o   w o r l d

やはりばらばらになる。

ばらばらにしたものを、何かに渡してみる

関数呼出しに渡すその1

ためしに、...arrを3つの引数を受け取る関数に渡してみる。

var arr = [1, 2, 3]

function add(x, y, z) {
  return x + y + z
}

console.log(add(...arr)) // 6

なるほど。たしかに、

関数呼出しでは3つの引数として展開してくれている。

関数呼出しに渡すその2

この2つの配列をマージするケースを考えてみる。

var arr = [1,2,3]
var arr2 = [4,5,6]

arr.push(arr2)
console.log(arr) // [1, 2, 3, Array(3)]

普通にpushで書くとマージできない(当たり前だけど)

これじゃない。これがやりたいんじゃない。

ここで、

objectスプレッド演算子を使って展開した値を、

配列が持っている関数、pushに渡してみる。

var arr = [1,2,3]
var arr2 = [4,5,6]

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

おお。たしかに関数呼出し内で引数として展開されていることが確認できる。

なるほどねぇ。

配列に渡してみる

var str = 'hello world'
console.log([...str]) //  ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]

おー。確かに配列内で要素として展開されている。

これでsplitを使わなくても良くなるな。

まとめ

objectスプレッド演算子を使うと「ばらばらになる」

そのばらばらになったものを、関数に渡したり配列に渡したり、

Objectに渡したり(まだ試してないけど)することにより、

処理の記述が簡単になる。