通俗解释:深拷贝是内容拷贝,浅拷贝是地址拷贝
深拷贝
<script> // 深拷贝,引用数据类型复制一份,复制后修改数据内容互不影响 const obj = { id: 1, name: "andy", msg: { age: 18 }, color: ["pink", "blue"] } const o = {}; // 封装克隆函数 function deepClone(newObj, oldObj) { // 使用forin遍历,因为它可以遍历数组也可以遍历对象 for (let k in oldObj) { // 遍历旧对象取值,k是old的属性名,可以遍历数组和对象 //拿到旧数组的值,判断是否是复杂数据类型 let item = oldObj[k]; // 将复杂数据类型的值给item if (Array.isArray(item)) { // 先判断值是否是数组,如果是就递归循环这个数组并赋值 newObj[k] = []; // 将类型变成数组,是数组的话,k就是索引号 deepClone(newObj[k], item); // 将索引号给到数组,并将值赋值到相应的属性名下 } else if (item instanceof Object) { // 判断是否是对象 newObj[k] = {}; deepClone(newObj[k], item); } else { // 是普通数据类型.直接赋值 newObj[k] = item; } } } deepClone(o, obj); console.log(o);</script>
浅拷贝
// 浅拷贝 const obj = { id: 1, name: "andy", msg: { age: 18 }, color: ["pink", "blue"] } console.log("obj", obj); const o = {}; for (let k in obj) { // k是obj的属性名 obj[k]是obj的属性值 o[k] = obj[k]; // 将k属性名作为o的属性名,obj属性值给到o } console.log("o", o); // 浅拷贝语法糖 Object.assign(o, obj); console.log("合并", o); // 可以进行对象的合并 const obj1 = { test: 11 }; // 如果拷贝的值得属性于之前的有相同,则值会覆盖 Object.assign(obj1, { test: 1 }) console.log(obj1);
/** * 深度拷贝 */export const deepClone = function (obj, hash = new WeakMap()) { if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作 if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); // 可能是对象或者普通的值 如果是函数的话是不需要深拷贝 if (typeof obj !== "object") return obj; // 是对象的话就要进行深拷贝 if (hash.get(obj)) return hash.get(obj); let cloneObj = new obj.constructor(); // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身 hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { // 实现一个递归拷贝 cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj;}