4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JacaScriptのイテレータとジェネレータの概念について、自分自身が理解するためにもその基本をまとめます。

JavaScriptのイテレーターとイテラブル

■ イテレーターとは

シーケンス(配列やオブジェクトなど)を反復処理するためのオブジェクトであり、各要素を順番に返すためのオブジェクトを指します。イテレーターは以下の特徴を持っています。

  • プロトコルの実装
    イテレーターはnext()メソッドを持ち、このメソッドは次の値(value)と、シーケンスが終了したかどうかを示すフラグ(done)を返します。返されるオブジェクトは {value, done} という形式です。

    ・value: 現在の要素の値
    ・done: シーケンスが終了した場合はtrue、まだ要素が残っている場合はfalse

iterator.js
function iteratorSample(array){
    let index = 0;

    return {
        next: function(){
            if(index < array.length){
                return {value: array[index++], done: false};
            }else{
                return {value: undefined, done: true};
            }
        }
    }
}

const iterator = iteratorSample([1, 2, 3]);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

■ イテラブルとは

イテラブルとは、反復可能なオブジェクトを指し、JavaScriptでは、[Symbol.iterator]()メソッドを持つオブジェクトを意味します。iterator.jsのconst iteratorをイテラブルにするには、const iteratorを返す [Symbol.iterator] メソッドを作ると、イテラブルオブジェクトを作成できます。

sample.js
function iteratorSample(array){
    let index = 0;

    return {
        next: function(){
            if(index < array.length){
                return {value: array[index++], done: false};
            }else{
                return {value: undefined, done: true};
            }
        }
    }
}


const iterator = iteratorSample([1, 2, 3]);
const iterable = {};
iterable[Symbol.iterator] = () => {
    return iterator;
}

// iterator is not iterableのエラーが発生
// for(const x of iterator){
//     console.log(x);
// }

for(const x of iterable){
    console.log(x);
}

■ 文字列はイテラブルである

文字列がイテラブルであることを、下記のコードで確認できます。

sample.js
const str = "イテラブル";

// 1. [Symbol.iterator]メソッドを持っているかチェック
console.log(typeof str[Symbol.iterator]); // "function"

// 2. イテレータの取得と値の取得
const iterator = str[Symbol.iterator]();

console.log(iterator.next()); // { value: "イ", done: false }
console.log(iterator.next()); // { value: "テ", done: false }
console.log(iterator.next()); // { value: "ラ", done: false }
console.log(iterator.next()); // { value: "ブ", done: false }
console.log(iterator.next()); // { value: "ル", done: false }
console.log(iterator.next()); // { value: undefined, done: true }

// 3.for...ofループによる反復処理
for(const x of str){
   console.log(x); // イテラブル
}

JavaScriptのジェネレーターとジェネレーター関数

ジェネレーターの解説をする際、ジェネレータージェネレーター関数 という2つのキーワードがでてきます。少しややこしいので、初めにその関係性を説明します。

ジェネレータ関数は、特別な構文(function* 構文)で定義された関数であり、その結果生成されるのがジェネレーターです。

■ ジェネレーターとは

ジェネレーターとは、イテレーターかつイテラブルであるオブジェクトのことを指します。

  • イテレーターである: next()メソッドを持ち、値を生成することができます。
  • イテラブルである: [Symbol.iterator]()メソッドを持ち、自身を返すことができるため、イテラブルなオブジェクトとしても機能します。

■ ジェネレーター関数とは

ジェネレーター関数は、function*構文を使用して定義される関数です。この関数では、yieldキーワードを使用して、一時停止しながら複数の値を生成することができます。最初に呼び出されると、ジェネレーター関数はコードを実行せず、ジェネレーターと呼ばれるある種のイテレーターを返します。

sample.js
// ジェネレータ関数 「function*」という構文を使用
function* generatorSample(){
    yield 1;
    yield 2;
    yield 3;
}

// 呼び出されると実行されず、代わりにジェネレータオブジェクトが返されます。
const gen = generatorSample();
console.log(typeof gen);// object
console.log(Object.prototype.toString.call(gen)) // [object Generator]

// イテレーター
console.log(gen.next()); // { value: 1, done: false }

// イテラブル
for (const value of gen) {
    console.log(value); // 2, 3
}

ジェネレーター関数は内部状態を保持することができるため、前回の呼び出し時の変数の値を引き続き使用することができます。

sample.js
function* counter() {
    let count = 0;
    while (true) {
        yield count++;
    }
}

const gen = counter();
while ((result = gen.next()).value < 100) {
    console.log(result.value); // 0から99まで出力
}

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?