Reputation: 55729
Why do map
, foreach
, and reduce
, not use the iterator function on Symbol.iterator
?
class MyArray extends Array {
*[Symbol.iterator]() {
for(let x = 0; x < this.length; x++) { yield this[x]*2 }
}
}
const log = console.log
const arr = new MyArray(1,2,3)
console.log([...arr]) // [2,4,6]
log(arr.map((i) => i)) // [1,2,3]
And:
const arr = [1,2,3]
Object.defineProperty(Object.getPrototypeOf(arr), Symbol.iterator, {
value: function*() {
for(let x = 0; x < this.length; x++) { yield this[x]*2 }
}
})
const log = console.log
log([...arr]) // [2,4,6]
log(arr.map((i) => i)) // [1,2,3]
Upvotes: 6
Views: 349
Reputation: 413682
The "old" Array methods are explicitly specified such that iteration is in terms of a simple sequence of numeric indexes. See for example the ES2016 spec.
You can use Array.from(arr)
to make your iterator work, and then call .forEach()
on the result.
Note that for some of the iteration methods, the specified behavior is to only invoke the callback for indexes that actually have an assigned value. Because using the iterator would mean iterating through all the values, that would be problematic. All the iterator function can do for unassigned values is return undefined
, but then it'd be ambiguous; does it mean the slot in the container has never been assigned a value, or does it mean it was explicitly assigned undefined
?
Upvotes: 3