如果我在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)
}
然而,这种情况却异常罕见。如果确实,那么提供映射的人可能实际上想要不同的迭代逻辑。