深拷贝函数
1、深拷贝基础
- 对象赋值的三种方式
- 引用赋值:指向同一个对象,相互之间会影响;
- 浅拷贝:浅层的拷贝,内部引入对象时,依然会相互影响;
- 深拷贝:两个对象不再有任何关系,不会相互影响;
- 实现深拷贝的方式:
- 通过JSON序列化
- 但是会存在bug
- 对函数、Symbol等无法处理
- 如果存在对象循环引用,会报错
- 自定义深拷贝函数
- 实现深拷贝基本功能
- 对Symbol的key做处理
- 对其他数据类型的值进行处理:数组、函数、Symbol、Set、Map
- 对循环引用做处理
2、基本实现
function deepClone(originValue) {
const newObject = {};
for (const key in originValue) {
newObject[key] = originValue[key];
}
return newObject;
}
const obj = {
name: 'byj',
age: 18,
friend: {
name: 'abc',
},
};
const newObj = deepClone(obj);
console.log(newObj === obj);
function isObject(value) {
const valueType = typeof value
return (value !== null) && (valueType === "object" || valueType === "function")
}
function deepClone(originValue) {
if (originValue instanceof Set) {
return new Set([...originValue]);
}
if (originValue instanceof Map) {
return new Map([...originValue]);
}
if (typeof originValue === "symbol") {
return Symbol(originValue.description)
}
if (typeof originValue === "function") {
return originValue
}
if (!isObject(originValue)) {
return originValue
}
const newObject = Array.isArray(originValue) ? []: {}
for (const key in originValue) {
newObject[key] = deepClone(originValue[key])
}
const symbolKeys = Object.getOwnPropertySymbols(originValue);
for (const sKey of symbolKeys) {
newObject[sKey] = deepClone(originValue[sKey]);
}
return newObject
}
let s1 = Symbol("aaa")
let s2 = Symbol("bbb")
const obj = {
name: 'byj',
age: 18,
friend: {
name: 'abc',
},
hobbies: ["abc", "cba", "nba"],
foo: function( ) {
console.log("foo function")
},
[s1]: "abc",
s2: s2,
set: new Set(['aaa', 'bbb', 'ccc']),
map: new Map([
['aaa', 'abc'],
['bbb', 'cba'],
]),
};
const newObj = deepClone(obj)
console.log(newObj === obj)