JSON 对象在浏览器中顺序与后端接口返回不一致的问题

一、问题描述

后端接口返回一个字典表的JSON对象,页面展示排序与预期排序不一致。

在浏览器调试面板Response中看到接口原始响应字符串,是期望顺序:

在Preview中看到, key "22" 被提到最前,顺序发生变化:

页面展示排序与Preview中看到的一致,与后端返回的不一致。

二、原因

问题发生在浏览器将接口返回的JSON对象格式字符串解析为JSON对象的过程中, JavaScript 引擎解析JSON对象时,遵循 ECMAScript 标准定义(ES6+ 开始统一行为)的 对象属性枚举顺序 的内部规范,JavaScript 对象属性的 对象属性枚举顺序 规则如下:

1. 整数索引属性

键为非负整数的字符串(例如 "0", "1", "22")会被优先枚举,按数值升序排列。

2. 普通字符串键(非整数)

如 "Ent01", "abc", "@type" 等,按插入顺序枚举,排在所有整数属性之后。

3. Symbol 类型键(不常见)

不参与常规的 for...in 和 Object.keys() 遍历。

因此,JSON对象字符串被JavaScript解析为JSON对象后,对象属性名为纯数字的排序在前,非数字字符排序在后,JSON对象的属性的顺序可能发生变化。

三、总结

这是一个由 JavaScript 对象内部规范引起的浏览器行为问题。

后端返回的是JSON对象格式,根据JSON的官方标准,JSON 对象的定义是一组无序的键值对,所以对顺序有要求的场景不应该使用对象结构,应该使用JSON中的数组。

JSON对象 和 JSON数组 的区别

特性 JSON对象 JSON数组
语法 用 {} 包裹,键值对形式 用 [] 包裹,值的有序集合
必须是字符串(双引号包裹) 无键,直接是值
值的顺序 无序 有序
用途 表示具有属性的数据(如对象、配置) 表示列表型数据(如数组、集合)
示例 {"张三": { "age": 25 }, "李四": { "age": 30 }} [ { "name": "张三", "age": 25 }, { "name": "李四", "age": 30 }]

如果无法通过修改代码结构解决,只能在设计需要排序的字段时,避免使用纯数字字符串作为键名。