前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库数组 keys values entries 迭代器区别
JSJavaScript数组与集合

数组 keys、values、entries 返回什么,为什么遍历第二次没有数据?

方法名决定每次产出的内容,而返回对象仍然是带进度的迭代器,不是已经收集好的数组。

前端进阶之旅 · 一题精讲更新于 2026.09.06
JavaScript#数组与集合
先看核心答案读代码示例
理解线索

一份数组的三种读取视角

  1. 索引序列keys 产生长度范围内的位置编号
  2. 值序列values 读取每个位置对应的值
  3. 位置和值entries 把索引和值组成一项返回

迭代器对象通常可以被继续消费,但已结束不会因为再次展开就自动重置;重新开始需要新的迭代器实例。

核心回答

先记住这个答案

数组 keys() 逐项产生数字索引,values() 产生对应值,entries() 产生 [索引, 值] 二元数组。它们返回可迭代的数组迭代器,可以用 next、for...of 或展开消费,并不会立即复制整个数组。同一个迭代器被读完后再次展开通常为空,需要重新调用方法获取新游标。对普通稀疏数组,keys 仍覆盖长度内的位置,values 与 entries 会读取缺失位置的值;这与只枚举自有可枚举字符串属性的 Object.keys 不同。若需要稳定快照,应明确复制时机。

  • keys、values、entries 改变产出内容
  • 返回的是有进度的迭代器而非结果数组
  • Object.keys 与数组 keys 的枚举范围不同

通过两次展开观察游标消耗

示例先保存 entries 迭代器,再展开两次,第二次为空。重新调用 entries 才创建新游标;这解释了为什么调试日志先展开查看后,真正业务循环可能已经无数据可读。

keys 与 values 的结果也用展开显示,但这一步是消费者主动收集的,不能反过来说方法本身返回数组。需要数组方法时可以先物化,若只按顺序读取则不必额外分配完整副本。

三种内容与一次游标的消耗JavaScript
const values = ['A', 'B'];
console.log(JSON.stringify([...values.keys()]));
console.log(JSON.stringify([...values.values()]));
const entries = values.entries();
console.log(JSON.stringify([...entries]));
console.log(JSON.stringify([...entries]));
console.log(JSON.stringify([...values.entries()]));
查看输出与解释
[0,1]
["A","B"]
[[0,"A"],[1,"B"]]
[]
[[0,"A"],[1,"B"]]

一个 entries 实例被第一次展开耗尽,第二次不再产生项;新调用返回的新迭代器从头开始。每个键值对里的索引是数字,不是 Object.keys 返回的字符串属性名。

稀疏数组让属性枚举差异更明显

new Array(3) 没有自有数字属性,但数组 keys 仍能产生零、一、二,因为它描述位置序列。Object.keys 则不会为这些缺失属性产生名称,二者长度可能完全不同。

若业务是遍历存在的记录,应确认是否允许稀疏输入,并选择检查自有属性还是处理所有位置。values 读取空位通常得到 undefined,原型上存在数字属性时还可能读到继承值,不能仅凭 length 推断真实记录。

迭代器不是创建时冻结的数据快照

尚未读取的值可能在消费期间被修改,数组长度变化也会影响尚未结束的迭代过程。若业务需要处理请求开始时那一批项目,应先建立受控快照,而不是保留一个游标就认为数据已经固定。

浅复制只能固定容器位置和当前元素引用,对象内部仍可能变化。批量处理若涉及并发更新,应定义快照层级、版本或稳定标识,避免把迭代顺序当作一致性协议。

回答前,多想一步

容易答错的地方

对 entries 返回值直接使用普通数组 map
返回值是迭代器,不能假定具有目标环境里的数组方法。需要数组时显式收集,或者按迭代协议处理;即便新环境提供迭代器助手,也与 Array.prototype.map 的返回和惰性语义不同。
调试时展开后继续复用同一个迭代器
日志输出已经消费游标,后续循环可能为空。应记录数据源的独立快照或新建一个迭代器,不要在排查中改变本来要交给业务处理的消费状态。
试着用自己的话回答

面试官还会怎么问?

entries 的每一项是原数组里的二元组吗?

不是,数组 entries 把当前位置索引和读取值组成二元数组。若原值本身也是数组,它只是二元组的第二项,不会自动展开;应根据具体嵌套结构解构而不是凭名字猜层级。

values 与默认数组展开有什么关系?

普通数组的默认迭代行为就是依次产生值,所以展开数组与消费其 values 迭代器通常得到相同序列。自定义 Symbol.iterator 可能改变默认展开,而显式调用内建方法仍应按各自契约分析。

已结束的迭代器遇到后来追加的数据会恢复吗?

不应依赖这种恢复;数组迭代器完成后会保持结束状态。需要读取新一轮数据应重新创建游标,并定义新旧批次边界,避免一个长期复用的迭代器承担不明确的增量订阅职责。

从一道题,走向一组知识

把知识连起来

数组与集合

怎样手写 Symbol.iterator,让普通对象支持 for...of 和数组展开?

自己实现独立游标,理解为什么读完不会自动重置。

数组与集合

稀疏数组空位与 undefined 有什么区别,为什么 Array(n).map 不执行?

对照位置数量、自有属性与 undefined 的差别。

参考资料

  • MDN:entries
  • MDN:Array

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 通过两次展开观察游标消耗
  3. 稀疏数组让属性枚举差异更明显
  4. 迭代器不是创建时冻结的数据快照
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑