本文内容基于 JavaScript 的内存管理机制,建议先了解变量存储方式
🧠 1. 核心本质:内存管理机制
JavaScript 中的深浅拷贝概念源于引用类型的内存管理机制,本质是为了解决如何独立复制引用类型数据的问题。
数据存储原理:
- 基本类型:值直接存储在栈空间,复制时创建独立副本
- 引用类型:值存储在堆空间,变量存储的是内存地址指针
// 基本类型 - 独立复制
let a = 10;
let b = a;
b = 20;
console.log(a); // 10(不受影响)
// 引用类型 - 共享指针
let obj1 = { x: 1 };
let obj2 = obj1;
obj2.x = 2;
console.log(obj1.x); // 2(被修改)
💡 深浅拷贝主要解决引用类型复制问题,基本类型复制天然独立
🍰 2. 浅拷贝:表层复制
2.1 核心本质
只复制对象的第一层属性,嵌套对象依然共享内存引用
2.2 常用实现方式
方法 | 适用类型 | 特点说明 |
---|---|---|
[...arr] | 数组 | 简洁高效 |
Object.assign({}, obj) | 对象 | 适合合并对象属性 |
arr.slice() | 数组 | 可截取片段 |
[].concat(arr) | 数组 | 适合合并多个数组 |
Object.create(obj) | 对象 | 原型继承(非严格复制) |
🛠️ 2.3 手写浅拷贝实现
const obj = {
name: 'FairyDiana',
age: 18,
money: Infinity,
lovers: {
one: '肖战',
two: '木村拓哉'
}
}
function shallowCopy(obj) {
let newobj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newobj[key] = obj[key];
}
}
return newobj;
}
const obj1 = shallowCopy(obj)
obj1.name = 'diana'
console.log(obj);
obj1.lovers.one = '魏无羡'
console.log(obj);
⚖️ 2.4 直接赋值 vs 浅拷贝
// 直接赋值 - 完全共享内存
const objA = { a: 1, b: { c: 2 } };
const objB = objA; // 完全共享内存地址
// 浅拷贝 - 创建新表层对象
const objC = Object.assign({}, objA);
// objC.a独立,但objC.b与objA.b共享内存
🧩 3. 深拷贝:完全独立复制
3.1 核心本质
创建对象的完全独立副本,所有层级属性都不共享内存引用
3.2 常用实现方式
方法1:JSON 序列化(简易版)
const deepCopy = JSON.parse(JSON.stringify(obj));
局限性:
- 不支持函数、undefined、Symbol、BigInt
- 会丢失特殊对象(Date/RegExp)的原型特性
- 无法处理循环引用
方法2:structuredClone(现代 API)
const deepCopy = structuredClone(obj);
优势:
- 支持 Date、Set、Map 等内置对象
- 处理循环引用
- 保持原型特性
限制:
- 不支持函数和 Symbol
- 浏览器兼容性问题
🛠️ 3.3 手写深拷贝实现(基础版)
const obj = {
name: "FairyDiana",
age: 18,
money: Infinity,
lovers: {
one: "肖战",
two: "木村拓哉",
},
};
function deepCopy(obj) {
let newobj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === "object") {
newobj[key] = deepCopy(obj[key]);
} else {
newobj[key] = obj[key];
}
}
}
return newobj;
}
const obj1 = deepCopy(obj);
obj1.name = "diana";
console.log(obj);
obj1.lovers.one = "魏无羡";
console.log(obj);
💎 总结:选择拷贝方式的黄金法则
场景 | 推荐方案 | 原因 |
---|---|---|
简单数据复制 | 浅拷贝 | 性能高效 |
需要完全独立副本 | 深拷贝 | 避免意外修改 |
含特殊对象的数据 | structuredClone | 保持类型完整性 |
简单 JSON 数据 | JSON.parse/stringify | 快速实现 |
循环引用数据 | structuredClone | 安全处理引用关系 |
理解本质:深浅拷贝的核心差异在于内存引用关系的复制深度。浅拷贝只断开第一层引用,深拷贝则递归断开所有层级的引用关系,创建真正独立的内存空间。