开发者问题收集

为什么迭代器对象变量未定义?

2020-10-20
170

学习在 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);
}

我得到“current 未定义”但据我所知,它是。我就是无法理解。我认为函数可以看到其范围之外的变量,但反之则不然,除非它们被“遮蔽”如果这是正确的术语。我忘了。

1个回答

current 不是变量,而是属性,因此您需要将其引用为 this.current

但是, this 存在另一个问题:

this.lengththis[a] 中, this 对象不是 arrayLikeObject ,而是具有 next() 方法的对象。

您也可以修复此问题,但我认为采用另一种方法更简单,将 next 设为箭头函数。这样 this.lengththis[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);
}
trincot
2020-10-20