オブジェクトにこのプロパティを指定すると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のthis
はSymbol.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: '...' } ]