为何Date在JSON.stringify的replacer函数中表现异常?
问题解答
现象原因
JSON.stringify对Date对象的处理有特殊逻辑:在调用你传入的replacer函数之前,它会先检查目标值是否拥有toJSON()方法。而Date类型原生自带toJSON()方法,这个方法会把Date对象转换为ISO格式的字符串。
所以当你通过JSON.stringify调用replacer时,传入的value已经是toJSON()处理后的ISO字符串;但你单独调用replacer时,直接传入了原始的Date对象,自然不会经过这个前置转换。这就是两种调用方式下value类型不一致的核心原因。
另外,this[key]能拿到原始Date对象,是因为replacer函数的this指向当前正在序列化的父对象,父对象里存储的还是未被修改的原始Date实例。
相关规范依据
这个行为在ECMAScript官方规范的JSON.stringify处理流程中有明确定义:
序列化每个值时,会先执行两步前置处理:
- 检查值是否存在
toJSON方法,若存在则调用该方法,用返回值作为后续处理的目标值;- 将经过
toJSON处理后的值传入replacer函数进行自定义处理。
实用解决思路
如果要把Date序列化为时间戳,可以在replacer里通过this[key]判断原始值是否为Date对象(因为value已经是字符串,无法直接判断类型),然后返回时间戳:
const replacer = function(key, value) { if (this[key] instanceof Date) { return this[key].getTime(); // 返回Unix时间戳 } return value; }; const data = { updateTime: new Date() }; const serialized = JSON.stringify(data, replacer); // 输出示例:{"updateTime":1700000000000}
内容的提问来源于stack exchange,提问作者Wang Tang
相关产品推荐
相关产品推荐

