スプレッド構文で遊んでみた
何となくオブジェクトを展開する便利な構文くらいでいたのですが、
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で使えません。