我遇到一个问题,我的后端将包含浮点数(例如 10.0、20.0)的 JSON 数据发送到 UI 端。然而,在 UI 中接收这些数字并将其记录到控制台后,我发现它们会自动转换为整数(10 和 20),而不是保留其原始的浮点格式。奇怪的是,带有小数部分的数字(例如 20.1)保持不变为 20.1。
我找到了我想要的解决方案。这是取自 stringify-with-floats npm 库,但经过修改以支持任何长度的浮点数。
const stringifyWithFloats = (config = {}, decimals = 1) => {
const beginFloat = '__FLOAT__BEGIN__';
const endFloat = '__FLOAT__END__';
return (inputValue, inputReplacer, space) => {
const inputReplacerIsFunction = typeof inputReplacer === "function";
let isFirstIteration = true;
const jsonReplacer = (key, val) => {
if (isFirstIteration) {
isFirstIteration = false;
return inputReplacerIsFunction ? inputReplacer(key, val) : val;
}
let value;
if (inputReplacerIsFunction) {
value = inputReplacer(key, val);
} else if (Array.isArray(inputReplacer)) {
value = inputReplacer.indexOf(key) !== -1 ? val : undefined;
} else {
value = val;
}
const forceFloat =
config[key] === "float" &&
(value || value === 0) &&
typeof value === "number" &&
!value.toString().toLowerCase().includes("e");
return forceFloat ? `${beginFloat}${value}${endFloat}` : value;
};
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 the stringifyWithFloats function
const customStringify = stringifyWithFloats({ foo: 'float', 'bar.baz': 'float' });
// Serialize the test input
const serializedJson = customStringify(testInput, null, 2);
// Output the serialized JSON
console.log(serializedJson);
输出:
{
"foo": 10.0,
"bar": {
"baz": 20,
"qux": {
"value": 30
}
}
}
现在是主要问题和问题。如何使这个正则表达式神奇地处理嵌套对象并在需要时将数字处理为浮点数。
在 JavaScript 中,不存在
integer
和 float
这两种不同的类型。任何数字都是 number
类型,可能包含也可能不包含小数。数字的表示形式将删除小数点的尾部零。因此 1.010100
将记录为 1.01
,5.00
将记录为 5
等(因为它是相同的数字)。
如果在 UI 中您想以 x 点的小数显示它,您可以将其转换为字符串,四舍五入到最接近的小数,并根据需要添加尾部零。
这可以通过内置函数来完成 x.toFixed(1)
示例:
const x = 5;
console.log(x) // 5
console.log(x.toFixed(1)) // 5.0
console.log(x.toFixed(3)) //5.000