LoginSignup
2
1

More than 3 years have passed since last update.

スプレッド構文で遊んでみた

Posted at

スプレッド構文で遊んでみた

何となくオブジェクトを展開する便利な構文くらいでいたのですが、
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
改めてMDNの定義を読んでみると、iterableなものなら使えるということだったので、
色々と実験してみました。

文字列を渡してみる

スプレッド構文を使えるのは関数の引数・配列リテラル・オブジェクトリテラルの3種なのでそれぞれ試します。

引数として渡したケース

function test(...params){params.forEach(p => console.log(p));}
test(...'abcd');

//以下出力結果
a
b
c
d

文字列にスプレッド構文というと妙な感じがしますが、普通に一文字ずつに分割されるようです。

配列

let array = [...'abcd'];
//[ 'a', 'b', 'c', 'd' ]

まあここも想定通りですね。

Object構文

let o = {...'abcd'}
//{ '0': 'a', '1': 'b', '2': 'c', '3': 'd' }

0から順番にキーとして一文字ずつObject化されます。
ここも大体想定通りですが、Typescriptにすると実はこれエラーが出ます。

typescriptの場合、何故かObject型でないと受け付けないようになっているようです。
typescriptでObjectのスプレッド構文を書くとObject.assignにコンパイルされるのでそのせいかとも思ったのですが、
typescriptでもObject.assign({},'abcd')は通るので謎です。

ジェネレータを渡してみる

var gen = function* () {
     yield 1;
     yield 2;
     yield 3;
 };

こんな感じのジェネレータ関数を作って試してみます。

引数と配列

function test(...params){params.forEach(p => console.log(p));}
test(...gen());
1
2
3

let array = [...gen()];
[1,2,3]

ここまでは大体予想通りです。
ちなみに、これらの構文を使った場合、generatorは最後まで回されますので、
使った後にgenerator.next();を呼ぶと{value:undefined:done:true}を返します。

ただ、Objectにした場合はちょっと挙動が予想と違いました。

let generator = gen();
let o = {...generator};
//{}
generator.next();
{ value: 1, done: false }

文字列とと同じように、0から順番にキーとしたObjectが出来るかと思ったのですが、
単に空オブジェクトが生成されるだけで、内部的にgenerator.next()が呼ばれることもないようです。
これはObject.assignと似たような仕様のようです。
(MDNを読む限り細かい仕様の違いはあるようですが)

ちなみに、Typescriptの場合はstringと同様にObjectで使えません。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1