I'm learning to make objects iterable in Javascript.
My object is:
var arrayLikeObject = {
0: "hello",
1: "there",
2: "crappy coder",
length: 3,
}
then I do this to make it iterable:
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};
}
}
};
};
then when I run it with:
console.log("after making it iterable: ==============");
for(let str of arrayLikeObject) {
console.log(str);
}
I get "current is not defined". But as far as I can see, it is defined. I don't understand. I thought functions could see variables outside their scope, but not the other way around, unless they get "overshadowed".
current
is not a variable, it is a property, so you would need to reference it as this.current
.
However, you have another issue with this
:
In this.length
and this[a]
, the this
object is not arrayLikeObject
, but the object that has the next()
method.
You can also fix this, but I think it is simpler to go the other way, and make next
an arrow function. That way this.length
and this[a]
will work as intended. Make current
a normal variable within the closure:
const 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(...arrayLikeObject);
Note that you don't really have to create a new function, as you can just assign Array.prototype[Symbol.iterator]
:
const arrayLikeObject = {
0: "hello",
1: "there",
2: "crappy coder",
length: 3,
}
arrayLikeObject[Symbol.iterator] = Array.prototype[Symbol.iterator];
console.log(...arrayLikeObject);