# JSON 序列化的问题

URL: https://caijiao.org/decimaljs/11-appendix/02-json
Source: docs/decimaljs/11-appendix/02-json.md
Description: 介绍在使用 decimal.js 时遇到的 JSON 序列化问题及其解决方法，确保数值数据在序列化和反序列化中的准确性。

decimal.js 的 Decimal 实例默认在进行 JSON 序列化时，会被转换为对象而非字符串或数字，导致序列化结果不符合预期，影响数据传输和存储。

## 常见表现

```js
import Decimal from 'decimal.js';

const num = new Decimal('123.456');
console.log(JSON.stringify({ amount: num }));
// 输出: {"amount":{}}
````

这是因为 Decimal 实例没有实现合适的 `toJSON()` 方法，导致序列化时输出空对象。

## 解决方案

### 1. 自定义 `toJSON` 方法

为 Decimal 原型添加 `toJSON` 方法，将其转为字符串：

```js
Decimal.prototype.toJSON = function() {
  return this.toString();
};

const num = new Decimal('123.456');
console.log(JSON.stringify({ amount: num }));
// 输出: {"amount":"123.456"}
```

### 2. 在序列化时手动转换

在调用 `JSON.stringify` 前，将 Decimal 实例转换为字符串：

```js
const obj = { amount: num.toString() };
console.log(JSON.stringify(obj));
// 输出: {"amount":"123.456"}
```

### 3. 使用 replacer 函数

在 `JSON.stringify` 时，使用 replacer 函数自动转换：

```js
function decimalReplacer(key, value) {
  if (value instanceof Decimal) {
    return value.toString();
  }
  return value;
}

console.log(JSON.stringify({ amount: num }, decimalReplacer));
// 输出: {"amount":"123.456"}
```

## 反序列化处理

接收端解析时，需要将字符串恢复为 Decimal：

```js
const jsonStr = '{"amount":"123.456"}';
const obj = JSON.parse(jsonStr);
obj.amount = new Decimal(obj.amount);
```

## 注意事项

* 保持序列化和反序列化的转换一致，避免类型混乱。
* 选择适合项目的方案，确保数据传输安全和准确。

---

合理处理 decimal.js 的 JSON 序列化，保证数值数据在前后端传输中的完整性和准确性。
