• ..

JavaScript

    Symbol.iterator

    オブジェクトにこのプロパティを指定するとfor..ofなど反復文で回る要素を自分で制御できます。またSymbol.iteratorにはGeneratorfunction* () {...}を使います。例えば以下では、1, 2, 3と表示されます。

    const something = {};
    something[Symbol.iterator] = function* () {
        yield 1;
        yield 2;
        yield 3;
    
        // *yield [1, 2, 3]
        // も同じ結果になる
    };
    
    for (const num of something) {
      console.log(num);
    }

    またスプレッド構文を使うことで配列を取得することもできます。

    const arr = [...something];
    console.log(arr);
    // [1, 2, 3]

    し 僕的にはArray::filterなどで1回では絞り込めないような時に使ったりします。

    例えば、配列がSlack-APIで取得できるような以下のような構造だとした時に、

    const items = [
      {type: '***'},
      {type: '...'},
      {type: 'bot'},
      {type: ',,,'}
    ];

    {type: 'bot'}まで絞り込みたい時などです。ちなみにGeneratorのthisSymbol.iteratorを埋め込んだ要素自身になります。

    const untilItemHasTypeIsBot = function*() {
      const len = this.length;
      let i = 0;
      while (i < len) {
        if (this[i].type === "bot") {
          break;
        }
        yield this[i];
        i++;
      }
    };
    
    items[Symbol.iterator] = untilItemHasTypeIsBot;
    console.log([...items]);
    // [ { type: '***' }, { type: '...' } ]