在 JavaScript 开发中,数组的 keys()、values() 和 entries() 方法均为**惰性迭代器(Iterator)**,而非普通数组。这意味着它们不会立即执行计算,也不会自动转换为数组,而是按插入顺序逐个产出数据。这种设计非常适合按需遍历、节省内存,尤其在处理大型数组或需要精细控制循环流程时,优势十分突出。

keys():只遍历索引
该方法返回一个产出数组索引(0, 1, 2…)的迭代器。适用于只需位置信息的场景,例如批量设置 DOM 属性、生成序号,或进行与索引相关的逻辑判断。
- 直接使用
for...of:for (const i of arr.keys()) { console.log(i); } - 转为数组后再操作:
Array.from(arr.keys()).filter(i => i % 2 === 0)(筛选偶数索引) - 注意:在稀疏数组中,
keys()仍然会产出所有索引(包括空位对应的索引),不会跳过空缺
values():专注元素值本身
返回一个产出数组每个元素值的迭代器。它避免了手动通过索引取值(arr[i]),语义更清晰,且返回的是原值的引用(对象/函数类型保持不变)。
- 结合
for...of进行渲染或校验:for (const val of arr.values()) { if (!val) throw new Error("空值不允许"); } - 转为数组后统计:
const sum = Array.from(arr.values()).reduce((a, b) => a + b, 0) - 无法反查索引——迭代器只提供值,不带位置信息
entries():同时拿到索引和值
返回键值对 [index, element] 的迭代器,这也是数组默认的迭代方式(arr[Symbol.iterator] === arr.entries())。非常适合需要“边读边改”或进行结构化处理的场景。
- 解构遍历最常用:
for (const [i, val] of arr.entries()) { console.log(`${i}: ${val}`); } - 转为数组便于后续映射:
Array.from(arr.entries()).map(([i, v]) => ({ id: i, data: v })) - 比分别调用
keys()和values()更高效——一次遍历完成配对,避免两次独立迭代造成顺序不一致的风险
通用注意事项
三者返回的都是单次可用的惰性迭代器,不具备数组方法(如 map、filter、length),且不能重复使用:
- 已遍历完的迭代器再次调用
next()始终返回{ done: true } - 如需多次使用,必须重新调用
arr.keys()等获取新迭代器 - 若需要链式操作,先用
Array.from()或扩展运算符转为数组:[...arr.values()] - 浏览器兼容性良好(Chrome 66+、Firefox 60+、Safari 12.1+),IE 不支持
