Создание итератора с ES6 - PullRequest
       7

Создание итератора с ES6

0 голосов
/ 22 ноября 2018

В этом вопросе много движущихся частей, но я собираюсь начать с моего первого неправильного понимания.

Контекст: Iterator определяется как объект, который реализует метод next(),что оба моих примера ниже.Разница в том, что я создаю объект с next() методом по-другому.В моем первом примере я создаю функцию, которая возвращает объект, содержащий метод next().Затем я назначаю переменную этой функции, поэтому, если я не ошибаюсь, я по сути делаю объект на лету с предопределенной функцией.

var letters = ["a","b","c"];

function createIterator(array) {
    var i = 0;

    return {                //return an Object with a next() method
        next: function(){
            i < array.length ?    //if statement
            {value: array[i++], done: false}:
            {value: undefined, done: true};
         }
    }
}

var myIterator = createIterator(letters);
console.log(myIterator.next()) //{value: a, done: false}
console.log(myIterator.next()) //{value: b, done: false}
console.log(myIterator.next()) //{value: c, done: false}
console.log(myIterator.next()) //{value: undefined, done: true}

Итак, поместив функцию createIterator внутрипеременная myIterator, каждый раз, когда я запускаю функцию next(), я получаю следующий элемент в массиве, который я передаю.

Хорошо, подумал я.Что, если я только что сделал Объект без функции?

var literal = {
    letters: ["a", "b", "c"],
    next: function(){        //same next function as before
        var i = 0;
        i < this.letters.length ? 
        {value: this.letters[i++], done: false}:
        {value: undefined, done: true};
         }
}

console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}

Я думаю, это связано с моим неправильным пониманием того, как я вызываю метод next() с различными способами создания моих Объектов.Это может быть что-то с областью действия, но я действительно не совсем уверен.

1 Ответ

0 голосов
/ 22 ноября 2018

В первом примере i фиксируется в замыкании, поэтому оно работает.Во втором примере i создается новым каждый раз, когда вы вызываете функцию.Вы могли бы сделать это свойство объекта:

var literal = {
    letters: ["a", "b", "c"],
    i: 0,
    next: function(){        //same next function as before
       return this.i < this.letters.length ? 
        {value: this.letters[this.i++], done: false}:
        {value: undefined, done: true};
         }
}

console.log(literal.next()) 
console.log(literal.next()) 
console.log(literal.next()) 
console.log(literal.next()) 

Конечно, вы также можете реализовать это таким образом, чтобы он работал в качестве итератора в других контекстах и ​​был проще:

var G = {
    letters: ["a", "b", "c"],
    [Symbol.iterator]: function*(){      
       yield *this.letters
    }
}

// now the object works as an iterable:
console.log([...G])
// or
let iter = G[Symbol.iterator]()
console.log(iter.next()) 
console.log(iter.next()) 
console.log(iter.next()) 
console.log(iter.next())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...