手写深拷贝函数
将自己的理解和知识点写在代码注释中.(习惯了)
实现深拷贝v1-基本实现
function isObject(value) {
const valueType = typeof value
return (value !== null) && (valueType === 'object' || valueType === 'function')
}
function deepCopy(originValue) {
// 判断是否是对象
if(!isObject(originValue)) {
return originValue
}
var newValue = {}
for(const key in originValue) {
newValue[key] = deepCopy(originValue[key])
}
return newValue
}
const obj = {
name: 'Fhup',
age: 18,
friend: {
name: 'xixi',
home: {
count: 5
}
}
}
const newObj = deepCopy(obj)
console.log(newObj);
obj.friend.home = 666
console.log(newObj);
实现深拷贝v2-其他类型
function isObject(value) {
const valueType = typeof value
return (value !== null) && (valueType === 'object' || valueType === 'function')
}
function deepCopy(originValue) {
// 判断是否是一个Set类型
if(originValue instanceof Set) {
return new Set([...originValue])
}
// 判断是否是一个Map类型
if(originValue instanceof Map) {
return new Map([...originValue])
}
// 创建一个新的Symbol
if(typeof originValue === 'symbol') {
return Symbol(originValue.description)
}
// 对函数进行处理(直接返回使用同一个,因为函数不需要修改)
if(typeof originValue === 'function') {
return originValue
}
// 判断是否是对象
if(!isObject(originValue)) {
return originValue
}
// 优化: 判断传入的是数组还是对象
var newValue = Array.isArray(originValue) ? [] : {}
for(const key in originValue) {
newValue[key] = deepCopy(originValue[key])
}
// 对Symbol的key进行特殊的处理
const symbolKeys = Object.getOwnPropertySymbols(originValue)
for(const skey of symbolKeys) {
newValue[skey] = deepCopy(originValue[skey])
}
return newValue
}
let s1 = Symbol('aaa')
let s2 = Symbol('bbb')
const obj = {
name: 'Fhup',
age: 18,
friend: {
name: 'xixi',
home: {
count: 5
}
},
hobbies: ['aaa', 'bbb', 'ccc', 'ddd'],
foo(){
console.log('foo function');
},
[s1]: 'xxx',
s2: s2,
set: new Set(['111', '222', '333']),
map: new Map([['one','oonnee'], ['two', 'ttwwoo'], ['three', 'tthhrreeee']])
}
const newObj = deepCopy(obj)
console.log(newObj);
obj.friend.home = 666
console.log(newObj);
console.log(obj.s2 === newObj.s2) // false
实现深拷贝v3-循环引用
function isObject(value) {
const valueType = typeof value
return (value !== null) && (valueType === 'object' || valueType === 'function')
}
function deepCopy(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)
}
var newValue = Array.isArray(originValue) ? [] : {}
map.set(originValue, newValue)
for(const key in originValue) {
newValue[key] = deepCopy(originValue[key], map)
}
const symbolKeys = Object.getOwnPropertySymbols(originValue)
for(const skey of symbolKeys) {
newValue[skey] = deepCopy(originValue[skey], map)
}
return newValue
}
let s1 = Symbol('aaa')
let s2 = Symbol('bbb')
const obj = {
name: 'Fhup',
age: 18,
friend: {
name: 'xixi',
home: {
count: 5
}
},
hobbies: ['aaa', 'bbb', 'ccc', 'ddd'],
foo(){
console.log('foo function');
},
[s1]: 'xxx',
s2: s2,
set: new Set(['111', '222', '333']),
map: new Map([['one','oonnee'], ['two', 'ttwwoo'], ['three', 'tthhrreeee']])
}
obj.info = obj
const newObj = deepCopy(obj)
console.log(newObj);
obj.friend.home = 666
console.log(newObj);
console.log(obj.s2 === newObj.s2) // false
console.log(newObj.info.info.info);