1、区别
拷贝的层级不同,
深拷贝是指每一层数据的改动都不会影响原对象和新对象。层层拷贝
浅拷贝只有第一层的属性变动不相互影响,深层数据的变动还是会相互影响。只拷贝一层
2、实现拷贝的方法有哪些
浅拷贝:Object.assign() 展开运算符… concat() slice ()
<script>
const obj = {
id: 110,
name: '紫陌',
msg: {
age: 18
}
};
//第一种方式
const a ={}
for(let i in obj){
// i 是属性名 obj[i]是属性值
a[i] = obj[i]
}
console.log(a);
//第二种方式 es6
const b = {};
Object.assign(b,obj)
console.log(b);
//第三种方式 es6
const c = {...obj}
console.log(c);
</script>
深拷贝:JSON.parse (JSON.stringfy()) jQuery.extend() 递归
<script>
const obj = {
id: 110,
name: '紫陌',
msg: {
age: 18
},
color: ['yellow', 'red']
};
const obj1={}
// 封装函数
function deepCopy(newObj,oldObj) {
for (let i in oldObj) {
// 判断我们的属性值属于那种数据类型
// 1. 获取属性值 oldObj[i]
let item = oldObj[i]
// 2. 判断这个值是否是数组
if(item instanceof Array){
newObj[i] = []
deepCopy(newObj[i],item)
// 3. 判断这个值是否是对象
}else if(item instanceof Object){
newObj[i] = {}
deepCopy(newObj[i],item)
}else{
// 4. 属于简单数据类型
newObj[i] = item
}
}
}
deepCopy(obj1,obj)
obj.msg.age = 222
console.log(obj);222
console.log(obj1);18
</script>
完整版
function isObjcet(obj) {
if (typeof obj == "object" && obj != null) {
return true;
}
if (typeof obj == "symbol" || typeof obj == "function") {
return true;
}
return false;
}
function deepClone(obj, map = new WeakMap()) {
//非object类型,直接返回obj本身
if (!isObjcet(obj)) return obj;
// 处理循环引用
if (map.has(obj)) {
return map.get(obj);
}
//处理日期,正则、错误
if ([Date, RegExp, Error].includes(obj.constructor)) {
return new obj.constructor(obj);
}
// 处理函数
if (typeof obj === "function") {
return new Function("return " + obj.toString())();
}
// 处理Symbol类型
if (typeof obj === "symbol") {
}
// 处理Map对象
if (obj instanceof Map) {
const clonedMap = new Map();
map.set(obj, clonedMap);
obj.forEach((value, key) => {
clonedMap.set(key, deepClone(value, map));
});
return clonedMap;
}
// 处理Set对象
if (obj instanceof Set) {
const clonedSet = new Set();
map.set(obj, clonedSet);
obj.forEach((value) => {
clonedSet.add(deepClone(value, map));
});
return clonedSet;
}
// 处理对象、原型链/symbol/数组
const proto = Object.getPrototypeOf(obj);
const clonedObj = Object.create(proto);
map.set(obj, clonedObj);
for (let key of Reflect.ownKeys(obj)) {//这里可以枚举出symbol
//只处理对象本身属性
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key], map);
}
}
return clonedObj;
}