← 返回题目列表

JavaScript 对象属性的遍历顺序是怎样的?

中等 第 27 / 29 题 更新于 2026/07/29
JavaScript对象遍历

简化版

现代 JavaScript 中,对象自有属性的常见遍历顺序大体是:整数索引键按升序,字符串键按创建顺序,Symbol 键按创建顺序。不同 API 是否包含不可枚举属性、继承属性和 Symbol 属性并不一样。

面试时要同时回答“顺序规则”和“遍历 API 覆盖范围”,比如 Object.keys 只返回可枚举自有字符串键,Reflect.ownKeys 返回全部自有键。

详细版

const s = Symbol("s");
const obj = {
  b: 1,
  2: 2,
  a: 3,
  1: 4,
  [s]: 5
};

console.log(Object.keys(obj)); // ["1", "2", "b", "a"]
console.log(Reflect.ownKeys(obj)); // ["1", "2", "b", "a", Symbol(s)]

整数索引键优先按数字升序,然后是普通字符串键按插入顺序,最后是 Symbol 键。

不要把对象当作严格有序 Map 使用。如果业务需要稳定插入顺序和任意键类型,优先考虑 Map

完整版教学

一、对象属性遍历要分两个问题

第一,哪些属性会被遍历出来。

第二,被遍历出来的属性按什么顺序排列。

很多回答只说“对象无序”或“按插入顺序”,都不够准确。现代规范已经定义了不少自有属性的顺序规则。

面试里要把“覆盖范围”和“顺序规则”拆开讲,答案会清楚很多。

二、属性键分三类

对象属性键主要有三类:

类型示例排序特点
整数索引键"0""2"按数字升序
字符串键"name""01"按创建顺序
Symbol 键Symbol("id")按创建顺序

注意 "01" 通常不是整数索引键,因为它不是规范意义上的数组索引形式。

三、数字样式键会提前

const obj = {};
obj.name = "Ada";
obj[2] = "two";
obj[1] = "one";
obj.age = 28;

console.log(Object.keys(obj));
// ["1", "2", "name", "age"]

虽然 name 更早创建,但整数索引键会排在普通字符串键之前。

四、常用 API 覆盖范围不同

API自有属性可枚举限制包含 Symbol包含继承
Object.keys
Object.getOwnPropertyNames
Object.getOwnPropertySymbols
Reflect.ownKeys
for...in

选择 API 时要先问自己需要哪类属性。

五、for…in 会遍历继承可枚举属性

const proto = { inherited: true };
const obj = Object.create(proto);
obj.own = true;

for (const key in obj) {
  console.log(key);
}

如果只想处理对象自身属性,要加判断:

if (Object.hasOwn(obj, key)) {
  // own only
}

六、业务需要稳定顺序时考虑 Map

对象适合表达记录结构,Map 更适合表达有序键值集合。

const map = new Map();
map.set("name", "Ada");
map.set(2, "two");
map.set(1, "one");

console.log([...map.keys()]); // ["name", 2, 1]

Map 按插入顺序迭代,也支持对象、函数等任意键。

七、常见误区与追问

  • 误区:对象属性完全无序。 现代规范对很多遍历场景定义了顺序。
  • 误区:对象属性总按插入顺序。 整数索引键会优先按升序排列。
  • 误区:Object.keys 能拿到所有属性。 它只拿可枚举自有字符串键。
  • 误区:for…in 只遍历自身属性。 它会遍历继承链上的可枚举字符串键。
  • 追问:Reflect.ownKeys 有什么特点? 它返回全部自有键,包括不可枚举和 Symbol。
  • 追问:什么时候用 Map 替代对象? 需要稳定插入顺序、任意键类型或频繁增删键值时。

八、加强记忆

顺序口诀:

integer index -> string -> symbol
升序          -> 插入序  -> 插入序

API 口诀:Object.keys 常规可枚举;Reflect.ownKeys 最全自有键;for...in 会走继承链。回答时用一个数字键提前的例子,很容易把规则讲透。