前端进阶之旅前端进阶之旅
  • 基础篇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 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Map size 与对象键数量获取
JSJavaScript数组与集合

Map.size 与 Object.keys().length 统计的到底是什么?

统计数量前先确定要数的是集合条目、对象属性,还是数组可用索引范围。

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

明确数量对应的数据空间

  1. 集合条目set 与 delete 管理的键值关系
  2. 对象属性按是否自有、可枚举和键类型选择范围
  3. 数组长度约束索引范围但可包含缺失位置

Map.size 是访问器,不是可以任意设置的容量字段。想清空条目应使用 clear,而不是给 size 赋零。

核心回答

先记住这个答案

Map.size 直接表示集合内部当前键值条目数,更新同一个键的值不会增加数量,删除条目会减少数量;给 Map 对象附加普通属性也不计入 size。普通对象没有自动维护业务属性总数的通用 length,Object.keys(obj).length 只统计自有、可枚举、字符串键。若需要包含 Symbol 或不可枚举属性,要选择对应枚举方法,例如 Reflect.ownKeys 的范围更广。数组 length 又是索引边界,不一定等于存在元素数。不同计数 API 回答不同问题,不能只因为都返回数字就互换。

  • Map.size 统计内部条目而非对象附加属性
  • Object.keys 只包含自有可枚举字符串键
  • 数组长度、对象键数与集合条目数不能混用

更新键与增加属性不会产生同一种计数

示例先更新 Map 的同一个键,数量仍为一,再添加普通 note 属性,size 依然为一。Object.keys(map) 却可以看到 note,因为它枚举的是对象属性,不读取内部条目。

第二部分为普通对象增加不可枚举属性和 Symbol,Object.keys 只保留公开字符串字段,Reflect.ownKeys 则看到全部自有键。哪一个数字正确取决于希望统计的范围。

同一对象上不同计数接口JavaScript
const map = new Map([['a', 1]]);
map.set('a', 2);
map.note = 'debug';
console.log(map.size, Object.keys(map).length);
const object = { visible: 1 };
Object.defineProperty(object, 'hidden', { value: 2 });
object[Symbol('tag')] = 3;
console.log(Object.keys(object).length, Reflect.ownKeys(object).length);
console.log(new Array(4).length, Object.keys(new Array(4)).length);
查看输出与解释
1 1
1 3
4 0

两个一来自不同存储空间,不能据此认为 Map 条目就是普通属性。稀疏数组长度四但没有自有索引,进一步说明 length 不是所有容器通用的成员计数。

计数结果要和业务字段定义一致

配置面板通常只关心可枚举业务字段,此时 Object.keys 可能合适;对象内部非枚举元数据和 Symbol 不一定应展示或计入用户字段数量。若需求是完整反射检查,则要采用更宽的范围。

继承属性又是另一层,for...in 可能包含原型链上的可枚举字符串键,不能不加筛选就拿来数自有字段。输入来自不同原型时尤其应明确所有权条件,避免统计结果随原型变化。

频繁计数时考虑分配与维护成本

Object.keys 会创建键数组,反复在热循环中调用可能带来额外遍历和分配。若数据本来适合动态集合且经常增删计数,Map.size 的接口更直接;但是否值得迁移还取决于键类型、序列化和更新方式。

手工维护对象 count 字段也需要让所有增删路径同步,漏一次更新就可能长期漂移。若没有实际热点,清晰的枚举计算通常更容易保证正确,不能为了避免一次小分配引入复杂双写状态。

回答前,多想一步

容易答错的地方

对普通对象读 length 当成字段数
length 只是可能存在的普通属性,除非对象自身定义了特定协议,否则不会随业务键增删自动更新。应选择与所需范围匹配的枚举方法,而不是依赖偶然同名字段。
给 Map.size 赋零来清空集合
size 没有普通写入语义,赋值不会按预期删除条目,并可能在严格模式下失败。清空应使用 clear,删除特定键应使用 delete,再通过 size 与 has 验证实际集合状态。
试着用自己的话回答

面试官还会怎么问?

更新一个 Map 键为什么不增加 size?

键已经存在时 set 替换对应值,集合里的键值关系数量没有增加。只有新增不同键才增加条目,判断是否不同仍依赖 Map 的键相等规则,对象键按身份而不是字段内容。

Object.keys 会包含 Symbol 吗?

不会,它只返回自有可枚举字符串键。需要 Symbol 可以使用对应 Symbol 枚举方法,或用 Reflect.ownKeys 获取全部自有键后按描述符筛选,先明确是否也需要不可枚举项。

数组的真实记录数量应该怎样数?

取决于缺失位置是否允许、继承索引是否应计入及每项是否合法。密集受控数组可以直接用 length,稀疏或未知输入则需按明确结构规则检查,不能用一个 API 无条件代表业务记录数。

从一道题,走向一组知识

把知识连起来

数组与集合

用普通对象当字典时为什么会读到原型属性,Map 能避免吗?

区分业务键、自有属性与原型继承的读取范围。

数组与集合

频繁检查成员存在时,Set.has 一定比 includes 更快吗?

把重复查询和额外分配放进实际工作负载比较。

数组与集合

WeakMap 的键只能是对象吗,它怎样影响垃圾回收?

理解弱键集合为什么不能提供同样的可枚举计数。

参考资料

  • MDN:Map.size
  • MDN:Reflect.ownKeys

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

本题目录
  1. 先记住这个答案
  2. 更新键与增加属性不会产生同一种计数
  3. 计数结果要和业务字段定义一致
  4. 频繁计数时考虑分配与维护成本
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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