• JS中的深拷贝与浅拷贝


      刚看完JS中的深浅拷贝,来记录分享一番,一起来开心的掉发吧。

      首先了解深浅拷贝之前来看看JS中的几种数据类型,分别有String、Number、Boolean、undefined、null、Object。es6还多了一种symbol,我们暂且先把他放一边。前面提到的几种数据类型前五种也就是String、Number、Boolean、undefined、null都是属于基本数据类型,而Object则是属于复杂数据类型,比如数组Array,日期date,正则reg等等都是属于Object。

      好了,知道这些以后再让我们来看看堆内存和栈内存。首先基本类型都是存放栈内存中,复杂数据类型存放在堆内存中。因为栈内存中的变量一般都是已知大小或者有范围上限的,算作一种简单存储,基本数据类型就是如此。而堆内存存储的对象类型数据对于大小这方面,一般都是未知的。个人认为,这也是为什么null作为一个object类型的变量却存储在栈内存中的原因。当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

      前面提到的数据类型和堆栈内存你可能会疑惑,我就来看看深浅拷贝知道这些干嘛,其实这都是为了更好的理解深浅拷贝。看下面代码先

    var arr = [1,2,3];
    
    var newArr = arr;  //[1,2,3]
    
    newArr.push(4) //[1,2,3,4]
    
    arr //[1,2,3,4]

      我们创建一个数组arr,然后新数组newArr = arr,这个时候两个数组的值相等。可是当我修改新数组newArr时,旧数组arr的值也跟着被修改。那么这是为何?

    原因就是上面所说当我们创建arr数组时,arr被分配到了堆内存中,在栈内存留下可以寻找到的指针,也就是说当我们创建新数组newArr时,赋予newArr的是arr在栈中的地址(指针),其实仍与旧数组arr共享同一个内存,所以修改新数组newArr后,旧数组arr也会被修改。ok,接着看下面两行代码

    var a = 1;
    
    var b = a; //1
    
    b = 2;
    
    a = 1

    这个时候出现的情况跟上面为什么不同,因为上面代码中的a,b只是基本类型,声明后都是保存在栈内存中,值虽然相同,但是两个相互独立,修改互不影响。这样一对比是不是清晰一点了。

    总结一下:当基本类型实现浅拷贝,存在栈内存中,那么相互独立,互不影响。

         当复杂类型实现浅拷贝,新对象与旧对象仍然同时指向堆内存的同一属性,互不独立,相互影响。

    上面提到的复杂类型的浅拷贝不清不楚,藕断丝连在一些场景就很讨人厌了,这个时候我们引入一个深拷贝的概念,什么是深拷贝,字面上的意思就是相比浅拷贝更深一层的拷贝咯。它可以将复杂类型的数据相互独立出来,互不影响。好了,上最后一段代码实现深浅拷贝

    function copy(obj) {
        if(typeof obj == "object") { //判断是否复杂类型
           var result = obj.constructor == Array ? [] : {};//判断数组类型或是object,数组即result=[],object即result={}
            for(let i in obj) {
                result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判断数据每一项是否是object
            }
        } else {
            var result = obj //基本类型直接拷贝
        }
      return result;
    }
  • 相关阅读:
    香洲区学区查询
    审批流程标识
    小技巧
    Python字符串操作
    Delphi删除动态数组的指定元素
    dephi 多种排序 算法
    [转载]模拟退火,遗传算法,禁忌搜索,神经网络
    Date类学习总结(Calendar Date 字符串 相互转换 格式化) 转
    Java静态嵌套类
    java中的匿名内部类总结
  • 原文地址:https://www.cnblogs.com/xzhan/p/10636866.html
Copyright © 2020-2023  润新知