JavaScript中浅拷贝和深拷贝均无法原生完整处理Error对象:浅拷贝仅复制引用,修改影响原实例;JSON方法丢失Error,structuredClone抛DataCloneError,Lodash转为普通对象且丢失原型与方法,手写需特殊处理。

JavaScript 中的浅拷贝和深拷贝都无法原生、完整地处理 Error 对象——这不是操作方式选得对不对的问题,而是语言机制和规范层面的限制。
浅拷贝对 Error 对象的行为
浅拷贝(如 Object.assign()、展开运算符 {...obj}、Array.from())只会复制 Error 实例的「属性引用」,但不会重建 Error 的内部状态。实际结果是:
- Error 对象本身是引用类型,浅拷贝后新旧对象指向同一内存地址
- 修改
error.message或error.stack会影响原始 error 实例 -
error instanceof Error在拷贝后仍为true,但这是因共享引用,而非真正复制
深拷贝方案对 Error 的兼容性
主流深拷贝方法对 Error 的支持情况如下:
-
JSON.stringify() + JSON.parse():完全丢失 Error —— 序列化后变成空对象{},且instanceof Error判定失败 -
structuredClone()(2026 年已广泛支持):不支持 Error 对象,会抛出DataCloneError异常 -
Lodash
cloneDeep():将 Error 转为普通对象(含message、name、stack字符串),但丢失原型链和方法(如error.toString()行为异常) -
手写递归深拷贝:默认不处理 Error;需显式判断
obj instanceof Error,然后用new Error(obj.message)重建,并手动赋值name和stack(注意:stack是只读属性,部分环境不可写,只能近似还原)
实用建议:如何安全携带 Error 信息
与其尝试“拷贝 Error”,不如按场景选择更可靠的方式:
立即学习“Java免费学习笔记(深入)”;
- 日志或错误上报:提取关键字段(
message、name、stack、cause)组成 plain object,再进行深拷贝 - 状态管理(如 Redux / Zustand):避免把 Error 实例存入 state;改用标准化错误结构,例如
{ type: 'NETWORK_ERROR', message: '…', timestamp: Date.now() } - 需要保留完整 Error 行为:不拷贝,而是用
try/catch+throw重新抛出;或封装为可序列化的错误类(继承Error并确保toJSON()方法返回安全字段)


















