复制对象最顺手的写法是展开运算符,但它是浅拷贝:只有第一层是新对象,嵌套的数组和对象仍然是同一个引用。
const user = { name: "小明", tags: ["php", "js"] };
const shallow = { ...user };
shallow.tags.push("css");
console.log(user.tags); // ["php", "js", "css"],原对象被改了
以前对付嵌套结构,常见的是 JSON 那一套:JSON.parse(JSON.stringify(user))。能用,但有硬伤——函数、undefined、Symbol 会直接丢,Date 会变成字符串,报错对象也会丢信息。
现在的首选是 structuredClone,浏览器和 Node 新版本都支持,嵌套结构完整复制:
const deep = structuredClone(user);
deep.tags.push("go");
console.log(user.tags); // ["php", "js", "css"],这次原对象没被动
它的限制也有:不能克隆函数和 DOM 节点,原型链会被拍平成普通对象。纯数据的配置、表单、接口返回值,用它都没问题。
我的选择标准很简单:纯数据用 structuredClone,确实需要保留方法的对象再考虑自己写递归或者引库。