JSON.stringify + JSON.parse 无法处理 Function 和 Symbol,因其被静默过滤;可用 structuredClone()、手写 deepClone 或 Lodash 的 cloneDeep 配 customizer 解决。

JSON.stringify + JSON.parse 这套组合根本无法处理 Function 和 Symbol——不是“处理不好”,而是直接跳过、彻底丢失。
因为 JSON 标准只认六种类型:字符串、数字、布尔值、null、数组、对象。函数和 Symbol 都不在其中,序列化时会被静默过滤掉,不报错也不提示。
比如:
const obj = {
name: 'Alice',
greet: () => console.log('hi'),
id: Symbol('user')
};
JSON.parse(JSON.stringify(obj)); // → { name: 'Alice' }
// greet 和 id 全没了怎么保留 Function 和 Symbol?
✅ 用 structuredClone()(推荐优先试)
现代环境(Chrome 98+、Firefox 94+、Node.js 18.13+/20.6+)原生支持:
基于三引擎设计,从微信文章、新闻和博客网页提取干净内容,支持标题作者日期元数据,多格式和批量处理。
const copy = structuredClone(obj);
它能正确克隆 Symbol、函数引用、Date、RegExp、Map、Set、BigInt 等。
⚠️ 注意:克隆的是函数引用,不是新函数体;若函数依赖 this 或闭包变量,行为可能变化,但至少不会消失。
✅ 手写递归 deepClone(兼容老环境 + 完全可控)
核心要点:
- 用
WeakMap记录已拷贝对象,防循环引用 - 遇到
typeof value === 'function',直接返回原函数(复用) - 遇到
typeof value === 'symbol',用Symbol(value.description)新建同描述符的 Symbol - 区分 Array、普通 Object、Map、Set、Date 等类型,分别处理
简易版示例(支持 Function/Symbol/循环引用):
function deepClone(obj, seen = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (seen.has(obj)) return seen.get(obj);
let clone;
if (typeof obj === 'function') {
clone = obj; // 直接复用函数
} else if (obj instanceof Date) {
clone = new Date(obj);
} else if (obj instanceof Array) {
clone = [];
} else if (obj instanceof Map) {
clone = new Map();
} else if (obj instanceof Set) {
clone = new Set();
} else if (typeof obj === 'symbol') {
clone = Symbol(obj.description);
} else {
clone = {};
}
seen.set(obj, clone);
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
clone[key] = deepClone(obj[key], seen);
}
}
// 处理 Symbol 键(for...in 不遍历 Symbol 键)
const symbolKeys = Object.getOwnPropertySymbols(obj);
for (const sym of symbolKeys) {
clone[sym] = deepClone(obj[sym], seen);
}
return clone;
}✅ Lodash 的 _.cloneDeep() + customizer(适合已有 Lodash 项目)
默认不保留函数,但可自定义:
const clone = _.cloneDeep(obj, (value) => {
if (typeof value === 'function') return value;
if (typeof value === 'symbol') return Symbol(value.description);
});不复杂但容易忽略

















