js常见问题总结-引用数据类型的深浅拷贝
1.数组对象的浅拷贝
复杂数据类型名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值,简单数据类型一经声明键值都存储在栈内存中。由此引出复杂数据类型的深拷贝与浅拷贝。
var nums = [2,6,4,8,10,9,15]
var numShallowCopy=nums.sort((a,b)=>a-b)
console.log(nums)//[2, 4, 6, 8, 9, 10, 15]
console.log(numShallowCopy)//[2, 4, 6, 8, 9, 10, 15]
上述代码中数组sort
方法对数组进行升序排序,会改变原数组nums
的值,而numShallowCopy
指向nums
的堆内存中的值。因此numShallowCopy
和nums
的输出结果都是一样的。这种情况称为浅拷贝(只拷贝引用)。
2.数组对象如何实现深拷贝?
var nums = [2,6,4,8,10,9,15]
var numDeepCopy=nums.slice(0).sort((a,b)=>a-b)//nums.slice(0) ~~~~ [...nums]
console.log(numDeepCopy)//[2, 4, 6, 8,9, 10, 15]
console.log(nums) //[2,6,4,8,10,9,15]
在es5中主要使用Array.prototype.slice
实现深拷贝
在es6中使用展开表达式实现深拷贝
3.关于es6展开运算符的问题?
//关于es6展开运算符 ...
const arr1 = [1, 1, 2, 3, 4, 3, 1]
const copy1 = [...arr1 ] //此时的 数组copy1得到的数据是深拷贝的arr1
arr1[1] = '修改'
console.log(copy1[1]) //输出:1
//第二种情况
const arr2 = [[1,2],[2,3]]
const copy2 = [...arr2 ] //此时的 数组copy2得到并不是深拷贝的数据
arr2[1][0] = '修改'
console.log(copy2[1][0]) //输出:修改
可以深拷贝
展开符对于存在复杂数据类型的第一级数据能完成深拷贝,我们可以把他理解为,把拷贝目标对象内的一级值做简单数据类型的声明创建操作,一经展开此时的一级值就存在栈内存里,由此完成深拷贝。
不能深拷贝
既然我们明白深拷贝和浅拷贝的区别以及展开运算符可以深拷贝的原理 那么不能深拷贝的情况就自然而然理解了,因为展开数据的一级值是复杂数据类型即使 … 处理第二级的值依然是拷贝的栈内存的引用的地址,所以不能完成深拷贝。
值是复杂数据类型即使 … 处理第二级的值依然是拷贝的栈内存的引用的地址,所以不能完成深拷贝。
object对象同理