JSON.parse(JSON.stringify(obj))的弊端
-
这种深拷贝的方式其实对于函数,Symbol等是无法处理
-
并且如果存在对象的循环引用, 也会报错的
基本的深拷贝
/**
* 判断是否是一个对象
* @param {} value
* @returns
*/
function isObject(value) {
const valueType = typeof value;
return (value !== null) &&
(valueType === 'object' || valueType === 'function')
// function 也是个对象
}
function deepClone(originValue) {
// 如果不是对象是基本数据类型直接返回
if (!isObject(originValue)) {
return originValue
}
const newObject = {}
for (const key in originValue) {
newObject[key] = deepClone(originValue[key])
}
return newObject;
}
// 测试代码
let obj = {
a: 1,
b: 3,
c: {
d: {
f: 'test'
}
}
}
let cloneObj = deepClone(obj);
cloneObj.a = 'hello world'
console.log(obj, 'obj')
console.log(cloneObj, 'cloneObj')
输出结果
比较全的深拷贝
/**
* 判断是否是一个对象
* @param {} value
* @returns
*/
function isObject(value) {
const valueType = typeof value;
return (value !== null) && (valueType === 'object' || valueType === 'function') // function 也是个对象
}
function deepClone(originValue) {
// 是否是一个set类型
if (originValue instanceof Set) {
return new Set([...originValue]);
}
// 判断如果是symbol, 那么创建一个新的symbol
if (typeof originValue === 'symbol') {
return Symbol(originValue.description);
}
// 判断 如果是函数类型直接返回function
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])
}
// 对 symbol的key进行特殊处理
const symbolKeys = Object.getOwnPropertySymbols(originValue)
for (const sKey of symbolKeys) {
newObject[sKey] = deepClone(originValue[sKey]);
}
return newObject;
}
// 测试代码
let s1 = Symbol('ssss');
let s2 = Symbol('ddd');
let obj = {
name: 'coderAriel',
age: 30,
friend: {
name: 'james',
address: '广州'
},
hobbies: ['aaa', 'bbb', 'ccc'],
foo: function () {
console.log('foo function');
},
[s1]: 'ssss',
s2: s2,
set: new Set(["aaa", 'bbb', 'ccc']),
}
let cloneObj = deepClone(obj);
cloneObj.a = 'hello world'
console.log(obj, 'obj')
console.log(cloneObj, 'cloneObj')
console.log(cloneObj.s2 == obj.s2, 'symbol是否相等');
结果