почему переменная объектов итератора не определена?

#javascript #iterable

#javascript #итерируемый

Вопрос:

Учимся делать объекты итеративными в Javascript.

Объект:

 var arrayLikeObject = {
    0: "hello",
    1: "there",
    2: "crappy coder",
    length: 3,
}
  

затем я делаю это, чтобы сделать его итеративным:

 arrayLikeObject[Symbol.iterator] = function(){
    return {
        current: 0, // <---- but... it IS defined.
        next() {
            // let current = 0; // putting it here makes it work
            if(current < this.length) {
                let a = current;
                current  ;
                return {done: false, value: this[a]};
            }
            else {
                return {done: true};
            }
        }
    };
};
  

затем, когда я запускаю его с:

 console.log("after making it iterable: ==============");
for(let str of arrayLikeObject) {
    console.log(str);
}
  

Я получаю «ток не определен», но, насколько я вижу, это так. Я просто не могу понять. Я думал, что функции могут видеть переменные за пределами своей области видимости, но не наоборот, если только они не будут «затенены», если это правильная терминология. Я забыл.

Комментарии:

1. current -> this.current . Переменная и свойство объекта отличаются в JS.

2. Понял. Вроде как забыл, что это нужно использовать в методах объекта при создании объектного литерала, чтобы использовать свойства объектов в его методах:-o . Есть ли другое место для подобных вопросов, где кому-то просто нужна помощь, когда он мысленно заблокирован (после поиска в Google, проверки руководств и ответа на stackoverflow и все еще не может «отклеиться»).). Например, вторая пара глаз? Предполагая, что такого рода вопросы довольно быстро отклоняются x)

3. На самом деле. Только что заметил (из-за кучи других распечаток, мешающих. Он по-прежнему не работает, я больше не получаю ошибок при использовании if(this.current < this.length) , но я также не получаю результатов из цикла for …of .

Ответ №1:

current это не переменная, это свойство, поэтому вам нужно будет ссылаться на него как this.current .

Однако у вас есть другая проблема с this :

В this.length и this[a] this нет объекта arrayLikeObject , но есть объект, у которого есть next() метод.

Вы также можете это исправить, но я думаю, что проще пойти другим путем и создать next функцию со стрелкой. Таким образом this.length , и this[a] будет работать по назначению. Создайте current обычную переменную внутри замыкания:

 var arrayLikeObject = {
    0: "hello",
    1: "there",
    2: "crappy coder",
    length: 3,
}

arrayLikeObject[Symbol.iterator] = function(){
    let current = 0;
    return {
        next: () => {
            if(current < this.length) {
                return {done: false, value: this[current  ]};
            }
            else {
                return {done: true};
            }
        }
    };
};

console.log("after making it iterable: ==============");
for(let str of arrayLikeObject) {
    console.log(str);
}  

Комментарии:

1. Спасибо. Переписал его, явно создав объект, а затем после его заполнения, прежде чем возвращать его (объект, называемый итератором). Избегал функций со стрелками, поэтому приходилось отслеживать «это» и делиться им явно. Не хотел представлять еще одну вещь, функции со стрелками, которые мне не нравятся. Ваше объяснение полностью помогло, хотя :). Я принимаю ваш ответ.