如何让JSON序列化工具处理嵌套对象并保留指定浮点数格式
解决JSON序列化时嵌套对象指定字段保留浮点数格式的问题
问题背景
后端返回的JSON包含形如10.0、20.0的浮点数,UI接收后这类值会被自动转为整数(10、20),但业务需要保留浮点数格式;而带小数部分的浮点数(如20.1)能正常保留格式。基于stringify-with-floats修改的代码仅支持顶层字段保留浮点数,嵌套对象的指定字段(如bar.baz)无法生效。
原代码问题分析
原代码的jsonReplacer函数仅通过当前层级的key匹配配置项,没有跟踪字段的完整嵌套路径。当处理bar对象下的baz字段时,key是baz,而配置里的键是bar.baz,无法匹配,导致该字段未被标记为需要保留浮点数格式。
修改后的代码
核心修改是在replacer函数中跟踪当前字段的完整路径,用路径字符串匹配配置项:
const stringifyWithFloats = (config = {}, decimals = 1) => { const beginFloat = '__FLOAT__BEGIN__'; const endFloat = '__FLOAT__END__'; return (inputValue, inputReplacer, space) => { const inputReplacerIsFunction = typeof inputReplacer === "function"; // 跟踪当前字段的完整路径,用数组存储层级key const currentPath = []; const jsonReplacer = (key, val) => { // 处理根对象的初始调用(key为空字符串) if (key !== '') { currentPath.push(key); } let value; if (inputReplacerIsFunction) { value = inputReplacer(key, val); } else if (Array.isArray(inputReplacer)) { value = inputReplacer.indexOf(key) !== -1 ? val : undefined; } else { value = val; } // 生成完整路径字符串:用.连接层级key const fullPath = currentPath.join('.'); // 匹配配置:当前key或完整路径是否在config中 const forceFloat = (config[key] === "float" || config[fullPath] === "float") && (value || value === 0) && typeof value === "number" && !value.toString().toLowerCase().includes("e"); const result = forceFloat ? `${beginFloat}${value}${endFloat}` : value; // 退出当前层级时移除路径中的key if (key !== '') { currentPath.pop(); } return result; }; const json = JSON.stringify(inputValue, jsonReplacer, space); const regexReplacer = (match, num) => { return num.includes(".") || Number.isNaN(num) ? Number.isNaN(num) ? num : Number(num).toFixed(decimals) : `${num}.${"0".repeat(decimals)}`; }; const re = new RegExp(`"${beginFloat}(.+?)${endFloat}"`, "g"); return json.replace(re, regexReplacer); }; };
测试验证
使用原测试输入,配置嵌套路径:
// Test input const testInput = { foo: 10.0, bar: { baz: 20.0, qux: { value: 30.0 } } }; // Configure nested paths const customStringify = stringifyWithFloats({ foo: 'float', 'bar.baz': 'float', 'bar.qux.value': 'float' }); // Serialize const serializedJson = customStringify(testInput, null, 2); console.log(serializedJson);
输出结果:
{ "foo": 10.0, "bar": { "baz": 20.0, "qux": { "value": 30.0 } } }
所有指定的嵌套字段都成功保留了浮点数格式。
关键修改说明
- 路径跟踪:用
currentPath数组存储当前遍历的层级key,进入字段时push,退出时pop,确保路径正确对应当前遍历的层级。 - 完整路径匹配:生成
fullPath字符串(如bar.baz),同时支持匹配当前层级key(兼容原顶层字段配置)和完整嵌套路径。 - 根对象处理:跳过根对象的空字符串key,避免路径生成异常。
内容的提问来源于stack exchange,提问作者Feel free
相关产品推荐
相关产品推荐

