前端面试必考点:深拷贝和浅拷贝|8月更文挑战

856 阅读2分钟

这是我参与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)

结果如下:

深拷贝.PNG

这种方法首先通过JSON.stringify()方法转化为字符串,也就是基本数据类型,再通过JSON.parse()转化为数组,通过这两次的转换就实现了我们需要的深拷贝。这种方法已经足以应付日常工作中的使用。不过也有不好的地方,那就是可以深拷贝数组和对象,但不能深拷贝函数,网上有大佬写的js,可以实现任何数据类型的深拷贝,等我研究了再来补充。