什么是深拷贝函数::简单点来说,就是假设B复制了对象A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,如果B没变,那就是深拷贝
深拷贝方案01-简单的深拷贝函数,这种深拷贝函数的弊端是不能对对象里的函数和symbol进行处理。
const obj = {
name: 'lhm',
friend: {
name: 'kobe'
}
}
const info = JSON.parse(JSON.stringify(obj))
console.log(info === obj);
深拷贝方案02-实现深拷贝方法v1-基本实现
function isObject(value) {
const valueType = typeof value
const isObj = (value != null) && (valueType === "object" || valueType === "function")
return isObj
}
function deepClone(originValue) {
if(!isObject(originValue)) {
return originValue
}
const newObject = {}
for(const key in originValue) {
newObject[key] = deepClone(originValue[key])
}
return newObject
}
const obj = {
name: 'lhm',
age: 18,
friend: {
name: "james"
}
}
const newObj = deepClone(obj)
obj.friend.name = 'kobe'
console.log(newObj);
深拷贝方案03-实现深拷贝方法v2-其他的类型
function isObject(value) {
const valueType = typeof value
const isObj = (value != null) && (valueType === "object" || valueType === "function")
return isObj
}
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: 'lhm',
age: 18,
friend: {
name: "james"
},
hobbies: ["abc", 'cba', "nba"],
foo: function () {
console.log('foo function');
},
[s1]: "abc",
s2: s2,
set: new Set(["aaa", "bbb"]),
map: new Map([["aaa", "bbb"], ["abc", "cba"]])
}
const newObj = deepClone(obj)
obj.friend.name = 'kobe'
console.log(newObj);
深拷贝方案04-实现深拷贝方法v3-循环引用
function isObject(value) {
const valueType = typeof value
const isObj = (value != null) && (valueType === "object" || valueType === "function")
return isObj
}
function deepClone(originValue, map = new WeakMap()) {
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
}
if(map.has(originValue)) {
return map.get(originValue)
}
const newObject = Array.isArray(originValue) ? [] : {}
map.set(originValue, newObject)
for(const key in originValue) {
newObject[key] = deepClone(originValue[key], map)
}
const symbolKeys = Object.getOwnPropertySymbols(originValue)
for(const skey of symbolKeys) {
newObject[skey] = deepClone(originValue[skey], map)
}
return newObject
}
let s1 = Symbol("aaa")
let s2 = Symbol("bbb")
const obj = {
name: 'lhm',
age: 18,
friend: {
name: "james"
},
hobbies: ["abc", 'cba', "nba"],
foo: function () {
console.log('foo function');
},
[s1]: "abc",
s2: s2,
set: new Set(["aaa", "bbb"]),
map: new Map([["aaa", "bbb"], ["abc", "cba"]]),
}
obj.info = obj
const newObj = deepClone(obj)
obj.friend.name = 'kobe'
console.log(newObj);