如何实现JavaScript的深拷贝
程序员文章站
2022-07-07 19:43:11
如何通过自定义的deepclone,实现对对象,数组的深拷贝。 ......
在JavaScript中,对于引用类型来说,想要实现对一个对象的修改而不改变原来本身的对象,就需要对对象就行拷贝,拷贝分为深浅拷贝,如果一个对象或者一个数组中的value都是基本类型的话,那么通过浅拷贝就可以将一个对象复制,并且修改属性不会影响原来的对象,js中基本类型包括5种,分别是 String,Number,Boolean,Null,Undefined五种类型,也就是说如果你的引用类型中只有这5种类型的话,那么你只需要通过浅拷贝就可以实现。
var newobj = Object.assign({},obj);
但是对于一些复杂的类型,仅仅通过Object.assign来说就显得不是那么够了。ok,这里有两种方式可以实现,第一种,我们可以通过自己实现的一个deepclone来实现深拷贝
function deepclone(obj) { let newobj = Array.isArray(obj) ? [] : {}; //在这里判断传入的类型然后初始化一个空的对象或数组 for(let key in obj){ let type = Object.prototype.toString.call(obj[key]);//判断对象属性的类型,如果为引用类型递归处理 if( type === '[object Array]' || type === '[object Object]'){ newobj[key] = deepclone(obj[key]); } else{ newobj[key] = obj[key]; } } return newobj; }
通过这种方法我们就实现了一个对象的深拷贝,下面是测试的结果
var test = { score: [1,[3,4,5],3], name: 'petter', skill: { run: function () { console.log('I can run fast'); } } } var mytest = deepclone(test); mytest.name = 'jenny'; console.log('Myname is ' + test.name); mytest.score[1].push(4); console.log(mytest.score); console.log(test.score); mytest.skill.run = function () { console.log('I can\'t run fast'); } test.skill.run(); mytest.skill.run(); { score: [ 1, [ 3, 4, 5 ], 3 ], name: 'petter', skill: { run: [Function: run] } } Myname is petter [ 1, [ 3, 4, 5, 4 ], 3 ] [ 1, [ 3, 4, 5 ], 3 ] I can run fast I can't run fast
还有一种深拷贝的实现方法是通过json,当然这有点黑科技了
var newobj = JSON.parse(JSON.stringify(obj));
这种方法的缺点是对象的方法会丢失,因为对于JSON格式的数据来说是不应该有function的,所以在JSON.stringify中会帮我们将这些方法给滤掉,也就会造成丢失。
所以使用时应该多加小心。
ok,今天的总结就到这。