1、先看一下直接赋值的,直接进行地址的赋值,
//1、这个是直接进行赋值,所以两个的地址值是指向同一个,所以进行修改就会修改到原来的
const target = {
name: "lin",
};
const newObj = target;
target.name = "xxx"; // 改变原来的对象
console.log("原来的对象", target);
console.log("新的对象", newObj);
console.log("两者指向同一地址", target == newObj);
2、进行浅拷贝的,第一层是开辟空间进行新的赋值,深层的就是地址的复制。
// 2、这个是进行浅复制,和上面的直接赋值的不一样,指向不同的地址,但是仅仅就复制这一层,深的还是指向同一个地址。
import { clone } from "lodash";
const target = {
name: "lin",
};
const newObj = clone(target);
target.name = "xxx"; // 改变原来的对象
console.log("原来的对象", target);
console.log("新的对象", newObj);
console.log("两者指向同一地址", target == newObj);
3、深拷贝手写
// 3、深拷贝,是无论有多少层,都将其完整复制,即将其进行开辟新地址
function deepCopy(target, map = new Map()) {
if (target === null) return target; // 如果是null 就不需要进行拷贝操作
if (typeof target !== "object") return target; // 处理原始类型和函数 不需要深拷贝,直接返回
// 是引用类型就要进行赋值了
// 为了避免循环引用的问题,使用map来进行存储,比如说 var a = {a}, var b = deepCopy(a),
if (map.has(target)) {
return map.get(target);
}
// 创建一个新的克隆对象或克隆数组
var res = new target.constructor();
map.set(target, res);
// for (let key in target) { //因为forin是看不到Symbol的,所以说就是不能使用froin,所以使用Reflect.ownKeys
// if (target.hasOwnProperty(key)) {
// res[key] = deepCopy(target[key], map);
// }
// }
Reflect.ownKeys(target).forEach((key) => {
res[key] = deepCopy(target[key], map);
});
return res;
}