# 深拷贝和浅拷贝
浅拷贝是只拷贝对象的第一层的属性和值,如果拷贝的属性的值是一个对象,则拷贝的是对象的引用地址。
function shadowCopy(obj) {
var newObj = {};
for ([key, value] of Object.entries(obj)) {
newObj[key] = value;
}
return newObj;
}
var obj = { a: 'something', b: { c: 1 } };
const newObj = shadowCopy(obj);
newObj.a = 'hello world';
newObj.b.c = 2;
console.log(newObj, obj);
//result
//{ a: 'hello world', b: { c: 2 } } { a: 'something', b: { c: 2 } }
深拷贝的意思是拷贝所有属性和值,深拷贝前后两个对象是独立的,互相不影响。
function deepCopy(obj, map = new WeakMap()) {
//是否为基本类型数据
if (isObject(obj)) {
//判断是否为循环引用
if (map.get(obj)) {
return map.get(obj);
}
let type = [RegExp, Date, Set, Map, WeakMap, WeakSet];
if (type.includes(obj.constructor)) {
return new obj.constructor(obj);
}
let allDes = Object.getOwnPropertyDescriptors(obj);
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDes);
for (const prop of Reflect.ownKeys(obj)) {
cloneObj[prop] = isObject(obj[prop]) && typeof obj[prop] !== 'function' ? deepCopy(obj[prop], map) : obj[prop];
}
return cloneObj;
} else {
return obj;
}
}
function isObject(obj) {
return obj != null && (typeof obj === 'object' || typeof obj === 'function');
}
let obj = {
fun: function() {},
syb: Symbol('foo'),
a: undefined,
b: NaN,
c: Infinity,
reg: /^abc$/,
date: new Date(),
set: new Set([1, 2, 3, 4, 4]),
map: new Map([
['name', '张三'],
['title', 'Author'],
]),
text: 'aaa',
value: {
a: {
b: 2,
},
},
};
let cloneObj = deepCopy(obj);
obj.value.a.b = 3;
console.log('cloneObj', cloneObj);
console.log('obj', obj);
打印结果:
cloneObj {
fun: [Function: fun],
syb: Symbol(foo),
a: undefined,
b: NaN,
c: Infinity,
reg: /^abc$/,
date: 2020-09-09T04:31:06.705Z,
set: Set { 1, 2, 3, 4 },
map: Map { 'name' => '张三', 'title' => 'Author' },
text: 'aaa',
value: { a: { b: 2 } }
}
obj {
fun: [Function: fun],
syb: Symbol(foo),
a: undefined,
b: NaN,
c: Infinity,
reg: /^abc$/,
date: 2020-09-09T04:31:06.705Z,
set: Set { 1, 2, 3, 4 },
map: Map { 'name' => '张三', 'title' => 'Author' },
text: 'aaa',
value: { a: { b: 3 } }
}