Как сделать пользовательский интерфейс итератора повторяемым в JavaScript - PullRequest
2 голосов
/ 15 апреля 2020

У меня есть массив, и я переопределил его поведение Итератора по умолчанию. Проблема заключается в том, что после переопределения возвращаемый итератор становится не повторяемым и for..of..l oop завершается с ошибкой, но работает с массивом, но явный вызов метода итератора массива next () по-прежнему работает. Вот код ниже:

let arr = ["A", "B", "C", "D", "E", "F"];
arr[Symbol.iterator] = function(){
  let i = 0;

  return {
    //Iterator interface
    next:function(){
      //IteratorResult Interface
      return {
        value: arr[i++]+"..",
        done: arr[i] == undefined?true:false
      }
    }
  }
}

А вот объект итератора

let arrIterator = arr[Symbol.iterator](); //An iterator object returned but not iterable

Проба потребления с for..of..l oop на объекте итератора

for (let i of arrIterator){
  console.log(i);
}

ВЫХОД

for..of..loop trial on iterator result

Испытание потребления с for..of..l oop в массиве

for (let i of arr){
  console.log(i);
}

ВЫХОД

for..of..loop trial on array result

Испытание потребления с явным вызовом метода next ()

console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());
console.log(arrIterator.next());

ВЫХОД

explicit next() method call on iterator result

Пожалуйста, я действительно хочу знать, как сделать пользовательский итератор итеративным для for..of..l oop потребления.

Спасибо

1 Ответ

2 голосов
/ 15 апреля 2020

Вам необходимо также реализовать протокол Iterable ( вместо просто Iterator )

Добавьте [Symbol.iterator]: function() { return this; } к вашему объекту Iterator, и он будет работать.

let arr = ["A", "B", "C", "D", "E", "F"];
arr[Symbol.iterator] = function() {
  let i = 0;

  return {
    //Iterator interface
    next: function() {
      //IteratorResult Interface
      return {
        value: arr[i++] + "..",
        done: arr[i] == undefined ? true : false
      }
    },
    // Iterable interface
    [Symbol.iterator]: function() {
      return this;
    }
  }
}

let arrIterator = arr[Symbol.iterator](); //An iterator object returned but not iterable

for (let i of arrIterator) {
  console.log(i);
}

См. Итерационные протоколы для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...