一、为什么需要深拷贝?
js中的对象都会存储在堆内存中,而栈内存中保存的只是这个对象指向堆内存的地址;
当拷贝这个对象时,实际拷贝的是栈内存中的地址,但拷贝后的对象实际指向的还是保存在堆内存中的原对象;
这时候修改拷贝后的对象,原对象也会被修改,所以就需要深拷贝来解决这个问题。
二、实现深拷贝
1.原生手写
代码如下(示例):
function deepClone(obj) {
// 先判断obj是否是基本类型或null,如果是,则返回
if (typeof obj !== "object" || obj == null) {
return obj;
}
// 判断是数组还是对象
let res;
if (obj instanceof Array) {
res = [];
} else {
res = {};
}
// 使用递归来深拷贝
// for in 可以遍历数组也可以遍历对象
for (let key in obj) {
// 通过hasOwnProperty这个api
// 如果key属于obj的原型的属性就去递归
if (obj.hasOwnProperty(key)) {
res[key] = deepClone(obj[key]);
}
}
return res;
}
2.使用lodash库
首先安装lodash库
npm i lodash --save
使用起来及其简单,在需要使用的页面引入cloneDeep,然后直接将需要深拷贝的对象放进去即可,返回的对象就是经过深拷贝的对象。
import { cloneDeep } from "lodash";
export default {
methods:{
deepClone() {
const obj = [{a:1},{b:2}]
const newObj = cloneDeep(obj)
console.log(obj === newObj); //false
}
}
}
总结
手写深拷贝需要理解递归以及hasOwnProperty这个api的作用,最重要的是要想明白为什么需要深拷贝,直接赋值不香吗?为什么要这么麻烦的搞一个深拷贝,深拷贝解决了什么问题,以及实现深拷贝的思路,这些都要想明白。