直接迭代 Map 和通过 entries() 返回的迭代器迭代 Map 之间有区别吗?
Is there a difference between iterating a Map directly and via an iterator returned by entries()?
如果我在 JavaScript 中有一个 Map
,例如
const myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
那么这两个似乎都可以有效地遍历键值对
(以及我目前不感兴趣的许多其他选项):
// with .entries()
for (const [key, value] of myMap.entries()) {
//
}
// without
for (const [key, value] of myMap) {
//
}
有没有他们不这样做的极端情况?
Is there any edge case where they do not do the same?
没有。您从 entries
获得的迭代器对象与地图本身提供的完全相同。事实上,someMap[Symbol.iterator]
(当你向一个对象询问其迭代器时调用的函数)实际上与 someMap.entries
:
完全相同的函数
const someMap = new Map();
console.log(someMap[Symbol.iterator] === someMap.entries);
在规范中:
Map.prototype.entries
Map.prototype[@@iterator]
(@@iterator
是 Symbol.iterator
)——字面上只是指向 entries
默认情况下两者完全相同。
当使用 for...of
is used with a value as for (const item of collection)
then the well-known symbol @@iterator
查找值时。
对于 Map
个对象,@@iterator
will return .entries()
。这与调用方法完全一样,因为它 是 :
const map = new Map();
console.log(map[Symbol.iterator] === map.entries);
因此,两个循环将执行相同的操作。
小提示:即默认。如果 @@iterator
符号被覆盖,则可能有不同的结果:
const myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
myMap[Symbol.iterator] = function* () {
const entries = this.entries();
for (const [key, value] of entries)
yield [key, value.toUpperCase()]; //transform the value
}
// with .entries()
for (const [key, value] of myMap.entries()) {
console.log("with .entries()", key, value)
}
// without
for (const [key, value] of myMap) {
console.log("without", key, value)
}
然而,这种情况极少发生。如果它 确实 那么提供地图的人可能实际上 想要 不同的迭代逻辑。
如果我在 JavaScript 中有一个 Map
,例如
const myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
那么这两个似乎都可以有效地遍历键值对 (以及我目前不感兴趣的许多其他选项):
// with .entries()
for (const [key, value] of myMap.entries()) {
//
}
// without
for (const [key, value] of myMap) {
//
}
有没有他们不这样做的极端情况?
Is there any edge case where they do not do the same?
没有。您从 entries
获得的迭代器对象与地图本身提供的完全相同。事实上,someMap[Symbol.iterator]
(当你向一个对象询问其迭代器时调用的函数)实际上与 someMap.entries
:
const someMap = new Map();
console.log(someMap[Symbol.iterator] === someMap.entries);
在规范中:
Map.prototype.entries
Map.prototype[@@iterator]
(@@iterator
是Symbol.iterator
)——字面上只是指向entries
默认情况下两者完全相同。
当使用 for...of
is used with a value as for (const item of collection)
then the well-known symbol @@iterator
查找值时。
对于 Map
个对象,@@iterator
will return .entries()
。这与调用方法完全一样,因为它 是 :
const map = new Map();
console.log(map[Symbol.iterator] === map.entries);
因此,两个循环将执行相同的操作。
小提示:即默认。如果 @@iterator
符号被覆盖,则可能有不同的结果:
const myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
myMap[Symbol.iterator] = function* () {
const entries = this.entries();
for (const [key, value] of entries)
yield [key, value.toUpperCase()]; //transform the value
}
// with .entries()
for (const [key, value] of myMap.entries()) {
console.log("with .entries()", key, value)
}
// without
for (const [key, value] of myMap) {
console.log("without", key, value)
}
然而,这种情况极少发生。如果它 确实 那么提供地图的人可能实际上 想要 不同的迭代逻辑。