直接迭代Map和通过entries()返回的迭代器迭代Map之间有区别吗



如果我在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) {
//
}

是否存在他们不做同样事情的边缘情况?

是否存在它们不执行相同操作的边缘情况?

否。从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与作为for (const item of collection)的值一起使用时,则使用众所周知的符号@@iterator来查找值

对于Map对象,@@iterator将返回.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)
}

然而,这种情况却异常罕见。如果确实,那么提供映射的人可能实际上想要不同的迭代逻辑。

最新更新