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: '...' } ]