LoginSignup
1
1

More than 3 years have passed since last update.

【javascript】イテラブル

Last updated at Posted at 2020-07-15

この記事は以下の書籍を参考にして執筆しました。

イテラブルとはなにか

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){
  //処理
}

出典:入門JavaScriptプログラミング

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
}

出典:入門JavaScriptプログラミング

for..inはオブジェクトのプロパティを列挙する。

スプレッド演算子

イテラブルがスプレッド演算子が使用できる。

const num=[1,2,3,4,5,6,7,8,9]
const min=Math.min.apply(null,num)

出典:入門JavaScriptプログラミング

これをスプレット演算子で書くとこうなる。

const num=[1,2,3,4,5,6,7,8,9]
const min=Math.min.(..num)

出典:入門JavaScriptプログラミング

ポイント

  • num配列が単一の引数としてMath.minに渡される。
  • 配列のすべての値が別々の引数として渡される。

配列だけでなく文字列を含めたすべてのイテラブルでうまくいく。

スプレッド演算子がレスト演算子と同じ。

イテラブルを配列リテラルに展開

const surname = 'Isaacks'
const letters = [...surname]
console.log(letters)//["I", "s", "a", "a", "c", "k", "s"]

出典:入門JavaScriptプログラミング

スプレッドをイミュータブルなプッシュとして使用する

スプレッドを使用すれば既存の配列を新しい配列にコピーした上で新しい要素を追加できる。

function additem(item){
  return [...cart,item]
}

出典:入門JavaScriptプログラミング

pushを使うとこうなる。

function addItem(tem){
  const newCart=cart.slice(0)
  newCart.push(item)
  return newCart
}

出典:入門JavaScriptプログラミング

アローを使うともっと簡潔に

const addItem=item=>[...cart,item];

出典:入門JavaScriptプログラミング

配列のシャローコピー

配列で何らかの分割処理をしたいが
元の配列を変更したくない、という場合に便利

function processItem(items) {
  copy = [...items];
  //itemsを分割するのではなく、copyを分割する。
}

出典:入門JavaScriptプログラミング

シャローコピー
コピー元とコピー先が同じメモリ上のデータを参照している。

ディープコピー
コピー元とコピー先が別々のデータを参照している。

イテレータ:イテラブルの内部を調べる

@@iteratorプロパティを持ちiteratorプロトコルに従うオブジェクトはすべてイテラブル。
イテレータはnextメソッドを持つオブジェクト。
nextメソッドは以下の2つのプロパティを持つ

プロパティ 説明
done イテレータが反復処理を終えたかどうか
value イテレータが生成する次の値

出典:入門JavaScriptプログラミング

スプレッド演算子と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
      }
    }
  }
}

出典:入門JavaScriptプログラミング

次にこの関数をイテレータとして使用するいてラブルを作成する。

const primesIterable = {
  [Symbol.iterator]: primesIterator
};

const myPrimes = [...primesIterable]; //[2,3,5]

出典:入門JavaScriptプログラミング

これで作成できるが、nextメソッドとdoneプロパティを持つオブジェクトを返す関数---ジェネレータ関数を使うともっと簡潔

ジェネレータ関数はイテレータであると同時にイテラブル。

つまり、ジェネレレータ関数を直接反復処理できるし、別々のオブジェクトをイテラブルにするための@@iteratorメソッドとしても使用できる。

function* primesIterator() {
  yield 2;
  yield 3;
  yield 5;
}

const primesIterable = {
  [Symbol.iterator]: primesIterator
};

const myPrimes = [...primesIterable]; //[2,3,5]

出典:入門JavaScriptプログラミング

1
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
1
1