使用JSON.parse/$.parseJSON解析JSON时如何保留键值原始排序
问题场景
JavaScript开发中执行以下代码:
var obj = '{"2": "Apple","3": "Banana","4": "Orange","6": "Grapes","1": "Kiwi","7":"Melon","5": "Mango"}'; var parsed = $.parseJSON(obj); console.log(parsed);
执行后返回的对象会自动按键名升序排序,输出结果:
{ 1: "Kiwi", 2: "Apple", 3: "Banana", 4: "Orange", 5: "Mango", 6: "Grapes", 7: "Melon" }
这个重排行为和$.parseJSON没有关系,本质是ECMAScript 规范明确定义了普通Object的键遍历规则:值为正整数的类数组索引键,会被优先按数字升序排列,和键值写入、解析的顺序无关,哪怕用原生JSON.parse解析成普通对象,这类键都会被自动重排,没有办法直接让普通Object保留这类键的原始顺序。
保留原始键顺序的可行方案
要保留JSON字符串里键值对的原始排列顺序,只能更换存储结构,或者调整键的格式,两种常用方案如下:
方案1:解析为Map结构
ES6 新增的Map数据结构会严格按照键值对的插入顺序存储、遍历,只要在解析JSON时把键值对按原始顺序写入Map,就能完全保留顺序:
// 针对扁平JSON的顺序解析方法,嵌套结构可自行扩展递归逻辑 function parseJSONKeepOrder(jsonStr) { const result = new Map(); JSON.parse(jsonStr, (key, value) => { if (key) result.set(key, value); return value; }); return result; } const parsed = parseJSONKeepOrder(obj); // 遍历parsed时输出顺序和原始JSON完全一致:2→3→4→6→1→7→5
方案2:修改键名格式绕过整数键排序规则
如果你必须用普通Object存储,可以在生成JSON时给所有整数类键加固定前缀,让引擎不再把它识别为类数组索引,就不会触发自动排序:
// 键名加统一前缀k_,避免被识别为整数索引 const jsonStr = '{"k_2": "Apple","k_3": "Banana","k_4": "Orange","k_6": "Grapes","k_1": "Kiwi","k_7":"Melon","k_5": "Mango"}'; const parsed = $.parseJSON(jsonStr); // 此时对象的键顺序和原始字符串完全一致,取值时带上前缀即可,比如parsed.k_2
这个方案适合你能控制上游JSON生成逻辑的场景,改造成本很低。
提示:如果业务逻辑强依赖键的排列顺序,不要用普通Object存储整数键的键值对,规范层面的排序行为没有hack手段可以绕过。
内容的提问来源于stack exchange,提问作者woninana
相关产品推荐
相关产品推荐

