前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库对象整数键枚举顺序及原因
JavaScript对象与原型

对象里的数字键,遍历出来为什么总排在最前面?

对象自己的键分三组排:先是整数键,按数值从小到大;再是普通字符串键,按添加的先后;最后是 Symbol 键,也按添加先后。所以不管数字键写在哪,遍历出来都排在最前面。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#对象与原型
先看核心答案读代码示例
理解线索

自有键的三段排序

  1. 整数键形如 0、1、10 的数组下标式键,按数值升序
  2. 字符串键其余字符串键,按属性创建的先后顺序
  3. Symbol 键排在最后,只有 Reflect.ownKeys 等 API 能拿到

判断整数键看的是字符串形式:只有「转成数字再转回字符串还是原样」的非负整数才算,所以 '01' 和 '-1' 都会按插入顺序排。

核心回答

先记住这个答案

对象的自有键遍历时分三段:第一段是整数键,按数值从小到大排;第二段是其余字符串键,按添加的先后排;第三段是 Symbol 键,也按添加先后。所以 { b: 1, 2: 'x', a: 2, 1: 'y' } 用 Object.keys 遍历出来是 1、2、b、a。这是规范写死的,Object.keys、Object.entries、for...in、JSON.stringify 都遵守同一个顺序。

  • 整数键升序在前,字符串键按插入顺序在后
  • 01、-1、1.5 属于字符串键
  • 自有键遍历有约定的顺序
  • 要保证插入顺序,用 Map

看一个混合键的对象

业务里最常见的坑:后端返回一个以 id 为键的对象,比如 { "30": ..., "10": ..., "20": ... },前端想保留后端给的顺序,结果渲染出来变成了 10、20、30。

各种键混在一起的排序JavaScript
const obj = { b: 1, 10: 'ten', a: 2, 2: 'two', '-1': 'neg', '1.5': 'float', '01': 'lead' }
obj[0] = 'zero' // 最后才加,照样排第一
obj[Symbol('s')] = 's'

console.log(Object.keys(obj).join(','))
const forIn = []
for (const k in obj) forIn.push(k)
console.log(forIn.join(','))
console.log(JSON.stringify(obj))
console.log(Reflect.ownKeys(obj).length) // 8 个字符串键 + 1 个 Symbol
查看输出与解释
0,2,10,b,a,-1,1.5,01
0,2,10,b,a,-1,1.5,01
{"0":"zero","2":"two","10":"ten","b":1,"a":2,"-1":"neg","1.5":"float","01":"lead"}
9

几个细节。0 是最后加的,但它是整数键,直接排到最前面。'-1'、'1.5'、'01' 看起来像数字,却都不算整数键,老老实实按插入顺序排在 b、a 后面。Symbol 键不会出现在 Object.keys 和 for...in 里,也会被 JSON.stringify 忽略,只有 Reflect.ownKeys 数得到它。

哪些键算整数键

规范里叫「数组索引」(array index):一个字符串,转成数字后是 0 到 2 ** 32 - 2 之间的整数,并且再转回字符串和原来一模一样。

按这个标准,'10' 算,'01' 不算(转回来是 '1'),'-1' 不算(负数),'1.5' 不算(不是整数),'1e3' 也不算。超出上限的大数字,比如 '4294967295',同样按普通字符串键处理,排在整数键后面。

对象字面量里写 { 1: 'a' },键会先被转成字符串 '1'。对象的键只有字符串和 Symbol 两种,数字键本质上也是字符串,只是符合上面的格式才被特殊排序。

为什么要这样排

历史原因和性能原因各占一半。

引擎在内部会把对象的整数键单独存在一块类似数组的连续存储里,V8 里叫 elements,其余命名属性存在另一处。遍历时先把 elements 按下标走一遍,再按创建顺序走命名属性,自然就是这个顺序。这样数组和类数组对象的下标访问能走快速路径。

早期规范并没有规定顺序,但主流浏览器实际行为都是这样。ES2015 先给 Reflect.ownKeys、Object.getOwnPropertyNames 这类 API 定下了顺序,后来 ES2020 又把 for...in 的顺序也规范化了,现在不同引擎之间结果一致,可以依赖。

回答前,多想一步

容易答错的地方

以为对象键完全按插入顺序
只有非整数的字符串键才按插入顺序。只要键像数组下标,就会被提到前面排序。所以用 id 当键存有序列表,顺序一定会乱。
以为 for...in 和 Object.keys 顺序可能不同
自有属性部分两者顺序一致。差别在于 for...in 还会接着遍历原型链上的可枚举属性,排在自有属性后面;Object.keys 只看自有属性。
以为数字字符串都算整数键
'01'、'-1'、'1.5'、' 1' 这些都是普通字符串键,按插入顺序排。判断标准是「转数字再转回来是否完全一样」。
试着用自己的话回答

面试官还会怎么问?

要保留后端返回的顺序,该怎么办?

让后端直接返回数组,或者前端用 Map 存。Map 严格按插入顺序遍历,不管键是什么类型。也可以另外维护一个存键顺序的数组,按数组去取对象里的值。

给键加个前缀能解决吗?

能。把 10 存成 'id_10',它就不是整数键了,会按插入顺序排。不少项目这样绕开,但读的时候要记得带前缀,不如直接用 Map 清楚。

数组的遍历顺序也是这个规则吗?

是的。数组本身就是对象,下标就是整数键,所以 Object.keys(['a', 'b']) 得到 ['0', '1']。如果给数组额外加了 arr.foo = 1 这种属性,它会排在所有下标后面。

从一道题,走向一组知识

把知识连起来

对象与原型

用 defineProperty 写 getter/setter,和直接在字面量里写 get/set 有什么不一样?

用 defineProperty 定义的属性同样按这套规则排序,只是默认不可枚举,Object.keys 里看不到。

对象与原型

Proxy 的 get 陷阱能做什么?怎么用它实现链式调用?

Proxy 的 ownKeys 陷阱可以自定义返回的键顺序,是绕开默认排序的一种办法。

参考资料

  • JavaScript:对象与原型参考资料

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

本题目录
  1. 先记住这个答案
  2. 看一个混合键的对象
  3. 哪些键算整数键
  4. 为什么要这样排
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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