JavaScript中for...in循环遍历对象数字键的顺序相关问题
关于for...in遍历数字字符串键顺序的问题解答
你观察到的现象是ES2015(也就是ES6)之后JavaScript标准明确规定的对象属性遍历顺序,和键的字符串类型并不冲突,规则细节如下:
前置常识
- 普通对象的键仅支持字符串、Symbol两种类型,你在定义对象时写的数字字面量键,会被引擎自动转为字符串格式存储,比如
{50: 'e'}实际存储的键是"50"。
标准规定的对象自有属性遍历顺序
for...in、Object.keys、Object.getOwnPropertyNames等常见的遍历对象属性的API,都会遵循以下优先级排序规则输出属性:
- 首先输出所有符合数组索引格式的字符串键:即内容为非负整数的字符串(比如
"50"、"120"都符合,"12.3"、"-40"不符合),这类键会按数值从小到大升序排列输出 - 其次输出所有普通字符串键(不符合数组索引格式的),按属性被创建的先后顺序排列输出
- 最后输出所有Symbol类型的键,同样按创建的先后顺序排列输出
你的测试用例执行逻辑
你测试传入的对象:
{ 9999: 'a', 120: 'b', 100000: 'c', 98: 'd', 50: 'e' }
所有键都被自动转为字符串,且全部符合数组索引格式,因此for...in遍历时会按数值升序输出,顺序为"50" → "98" → "120" → "9999" → "100000",你转成数字push进数组后,arr的内容就是[50, 98, 120, 9999, 100000]。此时你用arr.shift()取第一个元素(最小的50),arr.pop()取最后一个元素(最大的100000),最终结果自然符合预期。
补充注意
这个遍历顺序规则是ES2015才统一的,更早的ES5及之前的标准没有规定for...in的遍历顺序,部分老旧浏览器会按照属性创建顺序输出,如果你的代码需要兼容非常古早的运行环境,不建议依赖这个遍历顺序特性。
内容的提问来源于stack exchange,提问作者deepveeneck
相关产品推荐
相关产品推荐

