この記事は以下の書籍を参考にして執筆しました。
#イテラブルとはなにか
ES2015で追加されたiterableプロトコルに従うオブジェクトのこと。
String,Array,Set,Maoなど
これらのオブジェクトwhすべて共通のぷとロコルに従うため同じ挙動をする。
##for..of文
for (var i = 0; i < myArray; i++) {
car item = myArray[i];
//処理
}
このコードはfor..ofで書くとこうなる
for(const item of myArray){
//処理
}
for..ofによりイテラブルの値をループで処理できるようになった。
for..inとfor..ofの比較
const obj = {
series: 'Get Programing',
publicher: 'Manning'
}
const arr = ['Get Programing', 'Manning']
for (var name in obj) {
console.log(name) //series,publicher
}
for (var name of arr) {
console.log(name) //Get Programing,Manning
}
for..inはオブジェクトのプロパティを列挙する。
#スプレッド演算子
イテラブルがスプレッド演算子が使用できる。
const num=[1,2,3,4,5,6,7,8,9]
const min=Math.min.apply(null,num)
これをスプレット演算子で書くとこうなる。
const num=[1,2,3,4,5,6,7,8,9]
const min=Math.min.(..num)
####ポイント
- num配列が単一の引数としてMath.minに渡される。
- 配列のすべての値が別々の引数として渡される。
配列だけでなく文字列を含めたすべてのイテラブルでうまくいく。
スプレッド演算子がレスト演算子と同じ。
###イテラブルを配列リテラルに展開
const surname = 'Isaacks'
const letters = [...surname]
console.log(letters)//["I", "s", "a", "a", "c", "k", "s"]
###スプレッドをイミュータブルなプッシュとして使用する
スプレッドを使用すれば既存の配列を新しい配列にコピーした上で新しい要素を追加できる。
function additem(item){
return [...cart,item]
}
pushを使うとこうなる。
function addItem(tem){
const newCart=cart.slice(0)
newCart.push(item)
return newCart
}
アローを使うともっと簡潔に
const addItem=item=>[...cart,item];
###配列のシャローコピー
配列で何らかの分割処理をしたいが
元の配列を変更したくない、という場合に便利
function processItem(items) {
copy = [...items];
//itemsを分割するのではなく、copyを分割する。
}
シャローコピー
コピー元とコピー先が同じメモリ上のデータを参照している。
ディープコピー
コピー元とコピー先が別々のデータを参照している。
##イテレータ:イテラブルの内部を調べる
@@iteratorプロパティを持ちiteratorプロトコルに従うオブジェクトはすべてイテラブル。
イテレータはnextメソッドを持つオブジェクト。
nextメソッドは以下の2つのプロパティを持つ
プロパティ | 説明 |
---|---|
done | イテレータが反復処理を終えたかどうか |
value | イテレータが生成する次の値 |
スプレッド演算子とfor..ofはdoneプロパティにtrueが設定され、値がもう残っていないことを示すまでイテレータでnextメソッドを繰り返し呼び出す。
###@@iteratorとして使用できる関数の作成
オブジェクトをイテラブルにするには、新しいイテレータオブジェクトを返す@@iteratorメソッドを定義しなければいけない。
これから作る関数は以下のような機能を持っている。
- nextメソッドを持つ新しいオブジェクトを返す
- nextメソッドはdoneとvalueの2つのプロパティを持つ
function primesIterator() {
const primes = [2, 3, 5]
return {
next() {
const value = primes.shift();
const done = !value;
return {
value,
done
}
}
}
}
次にこの関数をイテレータとして使用するいてラブルを作成する。
const primesIterable = {
[Symbol.iterator]: primesIterator
};
const myPrimes = [...primesIterable]; //[2,3,5]
これで作成できるが、nextメソッドとdoneプロパティを持つオブジェクトを返す関数---ジェネレータ関数を使うともっと簡潔
ジェネレータ関数はイテレータであると同時にイテラブル。
つまり、ジェネレレータ関数を直接反復処理できるし、別々のオブジェクトをイテラブルにするための@@iteratorメソッドとしても使用できる。
function* primesIterator() {
yield 2;
yield 3;
yield 5;
}
const primesIterable = {
[Symbol.iterator]: primesIterator
};
const myPrimes = [...primesIterable]; //[2,3,5]