实现浅拷贝和深拷贝
1. 浅拷贝和深拷贝的区别
简单点说,浅拷贝拷贝完后,修改拷贝的内容可能会对源内容产生影响。而深拷贝就是拷贝前后的内容相互不影响。
那为什么拷贝前后的内容会相互影响呢?那就得知道原始数据类型和引用类型的区别了。
在内存中的存储方式不同,原始数据类型在内存中是堆存储,引用类型是栈存储 栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。在内存中存储方式的不同导致了原始数据类型不可变 原始数据类型和引用数据类型做赋值操作一个是传值一个是传址
- 原始数据类型:自然不用说了,它的值就是一个数字,一个字符或一个布尔值。
- 引用类型:是一个对象类型,值是什么呢?它的值是指向内存空间的引用,就是地址,所指向的内存中保存着变量所表示的一个值或一组值。
而在js中,有三大引用类型即Object、Array、Function。
因此在拷贝他们的时候,应该使用深拷贝来避免于源内容产生影响。
2.实现浅拷贝
2.1 object.assign()
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result= Object.assign(arr); arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
2.2 拓展运算符…
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN]; var result= [...arr]; arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
以上两种方法很简单,一句话就搞定啦。
3.实现深拷贝
3.1 JSON
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result = JSON.parse(JSON.stringify(arr));
arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
console.log(result); //output: [1, [7,[9]], {a:'111'}, null, null, null, null]
所以可以看出,使用JSON不能实现对function、undefined、NaN的拷贝。
如果拷贝的数据不存在function、undefined、NaN这些数据类型的话,使用JSON是个很简便的方法呢。
3.2 递归遍历
想要对所有类型都能够实现深拷贝的话,那就只能自己封装个函数来实现啦。
var arr = [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]; function deepCopy(arr) { if (typeof obj !== 'object') return; var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { if(obj[key]===null){newObj[key]=null;continue;} newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return newObj; } var result = deepCopy(arr)); arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]