深拷贝和浅拷贝原理
基础数据类型:
string、number、null、undefined、boolean、symbol
引用数据类型:
函数、对象、数组
产生原因:
基本类型是按值访问的,引用类型是按引用访问
1、基本类型的存储是放在栈区的

2、引用类型的存储是放在堆内存中的

当引用类型进行赋值的时候,JavaScript不允许直接访问内存中的位置,也不能直接操作对象中的内存空间。操作对象是直接操作对象的引用,而不是整个对象,所以就会出现深拷贝、浅拷贝的问题

浅拷贝只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块,
深拷贝是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象
浅拷贝实现方式:
1、对象使用Object.assign(target, source)方法
let testDeepObj2 = Object.assign({},testDeepObj1);
testDeepObj1对象中有引用类型的话,就是浅拷贝
2、数组使用slice()、concat()方法
var arr = ['jack',25,{hobby:'tennise'}];
let arr1 = arr.slice()
arr1[2].hobby='rose'
arr1[0]='rose'
console.log( arr[2].hobby) //rose
console.log( arr[0]) //jack
深拷贝实现方式:
1.JSON.parse(JSON.stringify()),这种方式的缺点是当对象里面有函数的话,深拷贝后,函数会消失
let arr1 = JSON.parse(JSON.stringify(arr))
2、手写递归函数实现深拷贝
function copy(obj){
let newobj = null; //声明一个变量用来储存拷贝之后的内容
//判断数据类型是否是复杂类型,如果是则调用自己,再次循环,如果不是,直接赋值即可,
//由于null不可以循环但类型又是object,所以这个需要对null进行判断
if(typeof(obj) == 'object' && obj !== null){
//声明一个变量用以储存拷贝出来的值,根据参数的具体数据类型声明不同的类型来储存
newobj = obj instanceof Array? [] : {};
//循环obj 中的每一项,如果里面还有复杂数据类型,则直接利用递归再次调用copy函数
for(var i in obj){
newobj[i] = copy(obj[i])
}
}else{
newobj = obj
}
console.log('77',newobj)
return newobj; //函数必须有返回值,否则结构为undefined
}
参考文献:https://blog.csdn.net/qq_34645412/article/details/106327826

浙公网安备 33010602011771号