keys()返回索引迭代器而非数组,仅遍历数字下标,不可链式调用filter等方法,需用for...of、Array.from()或展开语法消费,且只能使用一次。
keys() 是 Array.prototype 上的方法,调用后返回一个 Array Iterator 对象,只遍历索引(即数字下标),不包含值。它不会生成新数组,内存开销小,适合只关心位置的场景,比如批量重置某几列、按索引做条件跳过等。
常见误用是直接对返回值调用 map 或 forEach —— 迭代器没有这些方法,会报 TypeError: xxx is not a function。
for...of、Array.from() 或展开语法 [...arr.keys()] 消费它.keys().filter(...),得转成数组再操作keys() 仍会返回所有已声明索引(包括 undefined 占位处),不会跳过空槽如果只是想按顺序拿到每个索引并做简单操作(比如清空偶数位、记录起始偏移),for...of 是最直接且无额外内存分配的方式。
const arr = ['a', 'b', 'c', 'd'];for (const index of arr.keys()) { if (index % 2 === 0) { console.log(`处理索引 ${index}`); // 输出 0, 2 }}
for (let i = 0; i 更语义清晰,少写边界判断
break 提前退出循环时,记得用 return 或标记 break outer;
一旦要筛选、去重、排序或与其他数据结构交叉计算,就得把迭代器转为数组。此时性能差异基本可忽略,但语义和可读性更重要。
const arr = [10, 20, 30, 40, 50];const evenIndices = Array.from(arr.keys()).filter(i => i % 2 === 0);// → [0, 2, 4]// 或用展开语法(更简洁)const oddIndices = [...arr.keys()].filter(i => i % 2 === 1);
Array.from(arr.keys()) 和 [...arr.keys()] 行为一致,后者更常用arr.keys().toArray() —— 迭代器没有这个方法for...of + 手动收集,避免一次性全展开三者都返回迭代器,但产出内容不同:keys() 出数字索引,values() 出元素值,entries() 出 [index, value] 元组。选哪个取决于你是否需要值、是否需要配对。
data-index 属性)→ 用 keys()
entries(),避免重复查 arr[i]
for...of arr 或 arr.values()
for 循环真正容易被忽略的是:keys() 返回的迭代器只能消费一次。第二次遍历时为空,调试时反复 console.log([...arr.keys()]) 会得到意外结果。