json.stringify 的 replacer 参数不能实现真正深拷贝,仅用于序列化时过滤或转换字段,输出为字符串;适用于简单对象,不支持函数、undefined、symbol 等非 json 安全类型。

JSON.stringify 的 replacer 参数本身**不能实现真正意义上的深拷贝**,它只在序列化过程中控制哪些属性被包含、如何转换值,最终输出仍是字符串。但你可以利用它在序列化阶段**过滤、替换或跳过特定原始数据**,从而间接影响“拷贝后还原”的内容——前提是后续再用 JSON.parse 还原。这种方式适用于结构简单、无函数/undefined/Symbol/Date/RegExp 等非 JSON 安全类型的对象。
replacer 是函数时:按路径动态过滤字段
当 replacer 是函数时,它接收两个参数:key(当前属性名)和 value(当前属性值)。返回 undefined 表示该属性被排除;返回其他值则使用该值替代原值。
- 过滤掉所有值为
null或undefined的字段(undefined本就不会被序列化,但显式处理更明确) - 跳过指定字段名,例如
'password'、'_meta'、'__v' - 对敏感字段做脱敏,如将邮箱前缀替换为
*** - 忽略整个子对象(返回
undefined),比如跳过user.internalConfig
示例:
const user = {
name: "Alice",
password: "123456",
email: "alice@example.com",
settings: { theme: "dark", notifications: true },
_temp: "should be ignored"
};
const json = JSON.stringify(user, (key, value) => {
if (key === 'password' || key === '_temp') return undefined;
if (key === 'email') return value.replace(/^(.{1}).+@/, '$1***@');
return value;
});
// 输出:{"name":"Alice","email":"a***@example.com","settings":{"theme":"dark","notifications":true}}
replacer 是数组时:白名单式静态字段保留
当 replacer 是字符串数组时,它表示**仅保留数组中列出的键名**,其余一概忽略。注意:该数组只作用于最外层对象;对嵌套对象无效(除非嵌套对象也单独传入 replacer,但 JSON.stringify 不支持分层 replacer)。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 适合已知结构、只需提取固定几个字段的场景
- 无法按值过滤,也不能处理嵌套层级的条件逻辑
- 若数组含不存在的键,自动跳过,不报错
示例:
const data = { id: 1, token: "abc", name: "Bob", roles: ["admin"] };
const json = JSON.stringify(data, ['id', 'name', 'roles']);
// 输出:{"id":1,"name":"Bob","roles":["admin"]}
// token 被完全剔除
注意边界:replacer 无法绕过 JSON 的固有限制
即使 replacer 处理得再精细,以下情况仍会导致信息丢失或报错,这不是 replacer 能解决的:
-
函数、undefined、Symbol 类型的值:无论 replacer 返回什么,它们在序列化前就被静默丢弃(
undefined作为对象属性值时直接跳过;作为数组元素时变成null) -
Date、RegExp、Map、Set、BigInt 等类型:默认转成空对象
{}或抛错(如TypeError: Do not know how to serialize a BigInt),需在 replacer 中手动转为可序列化格式(如date.toISOString()) -
循环引用:直接报错
TypeError: Converting circular structure to JSON,replacer 无法拦截或修复 - 原型链与 getter 属性:JSON.stringify 只遍历自有可枚举属性,不触发 getter,也不保留原型
替代方案建议:需要真正深拷贝 + 过滤,请用专用工具
如果目标是「深拷贝 + 条件过滤」,而非「生成 JSON 字符串」,推荐更健壮的方式:
- 用 Lodash 的
cloneDeepWith:可自定义每个值的处理逻辑,支持跳过、替换、终止递归 - 手写递归拷贝函数:在遍历时判断类型、键名、值内容,灵活控制是否跳过或转换
- 结合
structuredClone(现代浏览器) + 后处理:先克隆,再遍历删除/修改字段
JSON.stringify + replacer 更适合作为「导出 JSON 数据前的轻量清洗步骤」,不是通用深拷贝方案。










