常用的深拷贝方法

一、简单版
在不使用第三方库的情况下,我们想要深拷贝一个对象,用的最多的就是下面这个方法。

JSON.parse(JSON.stringify());

这种写法非常简单,可以应对大部分的需求,但是它还是有很大缺陷的,比如拷贝其他引用类型、拷贝函数、循环引用等情况。

二、基础版本
首先,如果是浅拷贝的话,以很容易写出下面的代码:

function clone(target) {let cloneTarget = {};for (const key in target) {cloneTarget[key] = target[key];}return cloneTarget;
};

创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性依次添加到新对象上并返回即可。*

如果是深拷贝的话,考虑到我们要拷贝的对象是不知道有多少层深度的,我们可以用递归来解决问题,稍微改写上面的代码:

如果是原始类型,无需继续拷贝,直接返回
如果是引用类型,创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性执行深拷贝后依次添加到新对象上。

很容易理解,如果有更深层次的对象可以继续递归直到属性为原始类型,这样我们就完成了一个简单的深拷贝:

function clone(target) {if (typeof target === 'object') {let cloneTarget = {};for (const key in target) {cloneTarget[key] = clone(target[key]);}return cloneTarget;} else {return target;}
};

三、完整版本

deepClone = source => {const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象for (let keys in source) { // 遍历目标if (source.hasOwnProperty(keys)) {if (source[keys] && typeof source[keys] === 'object') { // 如果值是对象,就递归一下targetObj[keys] = source[keys].constructor === Array ? [] : {};targetObj[keys] = deepClone(source[keys]);} else { // 如果不是,就直接赋值targetObj[keys] = source[keys];}}}return targetObj;
}let str1 = {arr: [1, 2, 3],obj: {key: 'value'},fn: function () {return 1;}
};
let str3 = deepClone(str1);console.log(str3 === str1); // false
console.log(str3.obj === str1.obj); // false
console.log(str3.fn === str1.fn); // true


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部