深拷贝和浅拷贝的终极解决方案:JSON.parse的局限性你踩过坑吗?
🧑🏫 作者:全栈老李
📅 更新时间:2025 年 5 月
🧑💻 适合人群:前端初学者、进阶开发者
🚀 版权:本文由全栈老李原创,转载请注明出处。
大家好,我是全栈老李。今天咱们聊聊前端开发中一个看似简单却暗藏玄机的话题——深拷贝和浅拷贝。这玩意儿就像是你去复印店复印身份证,有时候你拿到的是完美复刻(深拷贝),有时候却只是个表面功夫(浅拷贝),背面信息全没了。
先搞明白基本概念
浅拷贝就像是你把手机里的照片发到电脑上,看起来是两张照片,但实际上它们指向的是同一个存储位置。修改其中一张,另一张也会跟着变。来看个代码例子:
// 浅拷贝示例 - 全栈老李
const original = {
name: '老李', skills: ['JavaScript', 'Vue'] };
const shallowCopy = Object.assign({
}, original);
shallowCopy.name = '老王'; // 基本类型,不影响原对象
shallowCopy.skills.push('React'); // 引用类型,原对象也被修改了
console.log(original.skills); // ['JavaScript', 'Vue', 'React'] 被影响了!
深拷贝则是完完全全的克隆,就像科幻电影里的克隆人,从里到外都是独立的个体。修改克隆体不会影响本体。
JSON.parse的"万能"解决方案?
很多同学一遇到深拷贝需求,第一反应就是:
// JSON方案 - 全栈老李
const deepCopy = JSON.parse(JSON.stringify(original));
这招确实能解决80%的场景,但它有几个致命缺陷:
- 函数丢失:JSON不支持函数序列化
- 特殊对象变普通对象:比如Date会变成字符串,RegExp会变成空对象
- 循环引用直接报错:对象自己引用自己时直接GG
- 原型链断裂:拷贝后的对象原型是Object而非原对象的原型
// JSON方案的问题演示 - 全栈老李
const problemObj = {
date: new Date