这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战
深拷贝和浅拷贝
深拷贝和浅拷贝是前端面试的必须考点,有必要把它搞清楚,深拷贝和浅拷贝究其原因和内存有很大的关系,js中的基本数据类型都保存在栈中,引用类型都保存在内存堆中,知道了这点就可以很容易的搞懂深拷贝和浅拷贝。废话不多说,上代码
何为深拷贝,何为浅拷贝
深拷贝就是b拷贝了a,b改变而不影响a,如下
//深拷贝
var a=3
var b=a
b=5
console.log(a,b)//结果为3,5,这就是某种意义上的深拷贝
//浅拷贝
var a=[1,2,3]
var b=a
b[0]=4
console.log(a,b)//结果为[4,2,3],[4,2,3]这就是浅拷贝,b的改变也影响了a
由上可知,深拷贝浅拷贝往往发生在对象的拷贝中,基本数据类型不会出现浅拷贝的问题,这也就是上面说的和内存有很大的关系,下面写一下如何实现深拷贝
简单的深拷贝
var a= [1,2,3,4,5]
var b= []
a.forEach(function(val){
b.push(val)
})
b[0] =9
console.log(a,b)//结果为[1,2,3,4,5],[9,2,3,4,5]
//这就是通过forEach实现的一个深拷贝,但不是一个完全的深拷贝,有缺陷,如下:
var a= [1,[2,3],4,5]
var b= []
a.forEach(function(val){
b.push(val)
})
b[1][0] =9
console.log(a,b)
//结果为[1,[9,3],4,5],[1,[9,3],4,5]
从上面代码可以看出,for循环确实可以实现简单的深拷贝,但存在缺陷,那就是for循环实现的深拷贝只能拷贝单维数据,如果存在多维的数据就达不到深拷贝的效果了。
比较方便且实用的深拷贝方法
var a= [1,[2,3],4,5]
var str = JSON.stringify(a)
var b = JSON.parse(str)
b[0]= 6
b[1][0] =7
console.log(a,b)
结果如下:
这种方法首先通过JSON.stringify()方法转化为字符串,也就是基本数据类型,再通过JSON.parse()转化为数组,通过这两次的转换就实现了我们需要的深拷贝。这种方法已经足以应付日常工作中的使用。不过也有不好的地方,那就是可以深拷贝数组和对象,但不能深拷贝函数,网上有大佬写的js,可以实现任何数据类型的深拷贝,等我研究了再来补充。