javascript 中实现了迭代协议(iterator protocol)的数据类型包括 array、typedarray、map、set、string、arguments 对象以及 dom nodelist。这些类型都内置了 [symbol.iterator] 方法,因此可以直接在 for...of 循环中使用,或者通过展开运算符 ... 和解构赋值进行遍历。

原生集合类型 Map 和 Set 的迭代行为有何不同
Map 和 Set 都实现了迭代协议,但它们的迭代器返回的内容不同。Map 的迭代器返回的是 [key, value] 数组对,而 Set 的迭代器直接返回集合中的值。两者默认都使用 entries() 作为迭代方法,这意味着调用 [Symbol.iterator] 时,Map 返回键值对,Set 返回单值。

const map = new Map([['a', 1], ['b', 2]]);
const set = new Set(['x', 'y']);
// Map 迭代输出 [key, value]
for (const item of map) {
console.log(item); // ['a', 1], ['b', 2]
}
// Set 迭代输出 value
for (const item of set) {
console.log(item); // 'x', 'y'
}
上述代码展示了 Map 和 Set 在 for...of 循环中的实际输出。Map 每次迭代产生一个包含两个元素的数组,第一个是键,第二个是值。Set 每次迭代直接产生集合中的元素。这种差异源于它们内部存储结构的不同,Map 需要维护键值映射,而 Set 仅维护唯一值的集合。
字符串与 Arguments 对象的迭代细节是什么
String 类型的迭代器按 Unicode 码点(Code Points)逐个返回字符,对于基本 ASCII 字符,每个字符对应一个码点;对于代理对(Surrogate Pairs),如 emoji,迭代器会正确返回完整的字符而非单独的码元。Arguments 对象是类数组对象,它也实现了迭代协议,允许直接使用 for...of 遍历函数参数,无需先转换为数组。

function testArgs(a, b, c) {
for (const arg of arguments) {
console.log(arg);
}
}
testArgs(1, 2, 3); // 1, 2, 3
const str = "Hello ?";
for (const char of str) {
console.log(char); // H, e, l, l, o, , ?
}
在 Arguments 示例中,arguments 对象虽然看起来像数组,但它不是真正的 Array 实例,却支持迭代协议。在 String 示例中,emoji 字符 ? 作为一个整体被迭代出来,这体现了 ES6 迭代器对 Unicode 的支持。这与传统的 charAt 或索引访问不同,后者可能会将代理对拆分为两个部分。
NodeList 是否在所有浏览器中都支持迭代协议
NodeList 是否实现迭代协议取决于浏览器的版本。在现代浏览器(如 Chrome 61+、Firefox 54+、Safari 10.1+)中,DOM 的 NodeList 已经实现了迭代协议,可以直接用于 for...of。但在旧版浏览器中,NodeList 没有 [Symbol.iterator] 方法,直接迭代会报错。为了兼容性,通常建议将 NodeList 转换为数组后再处理,或者使用 forEach(现代浏览器也支持 NodeList.prototype.forEach)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











