返回
浅析“深浅拷贝”的精髓,避开JS编程中的常见坑
前端
2024-01-30 23:12:18
深入浅出话拷贝
JavaScript 中的数据类型大致分为基本数据类型和引用数据类型。基本数据类型保存在栈数据结构中,按值访问,不存在深浅拷贝问题。引用数据类型保存在堆数据结构中,按引用访问,深浅拷贝就显得尤为重要。
深拷贝是完整复制数据的值(而非引用), 目的是避免拷贝后数据对原数据产生影响。与之相对的浅拷贝只复制引用,源数据和拷贝数据共享内存地址,导致修改其中任何一个,另一个也会受到影响。
浅尝辄止看浅拷贝
接下来,我们来揭秘浅拷贝的常用方法。
方法一:Object.assign()
let obj1 = { name: 'Tom', age: 20 };
let obj2 = Object.assign({}, obj1); // 浅拷贝
方法二:扩展运算符(...)
let obj1 = { name: 'Tom', age: 20 };
let obj2 = {...obj1}; // 浅拷贝
使用上述方法进行浅拷贝时,对象中的基本数据类型会被复制一份新的值,而引用数据类型则会指向同一个内存地址。因此,当修改浅拷贝对象中的引用数据类型时,原始对象中的数据也会受到影响。
拷贝利器说深拷贝
深拷贝实现相对复杂一些, 但其本质就是递归的克隆源对象, 直到对象中的所有引用数据类型都完成复制。常用的深拷贝方法有:
方法一:JSON.parse(JSON.stringify())
let obj1 = { name: 'Tom', age: 20 };
let obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝
方法二:递归函数
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj; // 基本数据类型或null直接返回
}
let newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
newObj[key] = deepCopy(obj[key]); // 递归复制属性值
}
return newObj;
}
let obj1 = { name: 'Tom', age: 20 };
let obj2 = deepCopy(obj1); // 深拷贝
使用上述方法进行深拷贝时,无论对象中的数据类型是基本数据类型还是引用数据类型,都会被复制一份新的值,从而避免了浅拷贝中引用数据类型指向同一个内存地址的问题。
结语
深浅拷贝是JS编程中常见的基础知识。理解深浅拷贝的原理和区别,并熟练掌握常用的深浅拷贝方法,是编写高质量JS代码的基础。希望本文对您有所帮助。