对于浅拷贝和深拷贝的理解

时间:2021-04-17 19:48:51

对于浅拷贝的理解

使用js在存入数组或对象是会在浏览器的栈空间存储指向堆空间的指针(及地址),而在堆空间存储真正的内容,访问时通过栈空间的地址来访问;

  1. 浅拷贝拷贝的是栈空间内存地址,并不是拷贝的内容;
    比如:对于数组的拷贝

    1 var arr=["北京","上海","广州","深圳","成都"]
    2 var newArr=arr;
    3 newArr[3]="杭州";
    4 console.log(arr);//0:"北京"1:"上海"2:"广州"3 : "杭州" 4 :"成都"
    5 console.log(newArr);//0:"北京"1:"上海"2:"广州"3 : "杭州" 4 :"成都"

     

----更改了一处,但是两个数组都更改了;这种简单的赋值等于知识一种浅拷贝。

  1. 对于数组深拷贝的方法

    1. 用数组的slice方法来进行拷贝

    2. 对于数组的slice方法的使用:
      (1)slice方法用于对数组的截取,返回的是一个截取后的数组,语法是:

      1 arrayObj.slice(starIndex,endIndex)

       


      参数说明:arrayObj--必填项,是需要从该数组中来截取数组;starInex--必填项,表示截取开始的位子的下标;endIndex--选填项,如果该项不填,则从开始位置截取到最后,如果starindex或endinex为负数,那么从结尾开始计数下标。

    3. 用concat方法,js的concat方法用于连接两个或多个数组,该方法不会改变原有数组,会返回连接后数组的副本,Arrayobj.concat(arrat1,array2,array3,...),该方法会将数组中的元素取出,放入一个新数组中,返回改数组。

      1 var arr=[1,2,3,4];
      2 var arr1=["北京","上海"];
      3 var newArr=arr.concat(arr1);
      4
      5 console.log("原数组:"+arr);
      6 console.log("新数组:"+newArr)
      7 //返回结果
      8 原数组:1,2,3,4
      9 新数组:1,2,3,4,北京,上海

       

    4. 采用递归函对数组进行深拷贝,如下:

       1 var arr=["a","s","d","f"];
      2 function deepCopy(arr,newArr) {
      3 newArr=newArr || [];
      4 for (var i in arr){
      5 if (typeof arr[i]==="object"){
      6 newArr[i]=arr[i].constructor===Array?[]:{};
      7 deepCopy(arr[i],newArr[i])
      8 }else {
      9 newArr[i]=arr[i]
      10 }
      11 }
      12 return newArr
      13 }
      14 var arr1=deepCopy(arr);
      15 arr1[3]="asdfed";
      16 console.log("原数组:"+arr);
      17 console.log("新数组:"+arr1);
      18 //返回结果
      19 原数组:a,s,d,f
      20 新数组:a,s,d,asdfed

       

    5. 同时也可以用jQuery中的extend属性进行拷贝

  2. 对象的深拷贝的方法:比如以下代码

     1 function Test(){
    2 this.name="xiaohong";
    3 this.age=18;
    4 this.run=function () {
    5 console.log("i can run")
    6 }
    7 }
    8 var test=new Test();
    9 console.log(test.age);
    10 test.run();
    11 function NewTest() {
    12 this.name="xiaowang";
    13 this.age=20;
    14 this.sing=function () {
    15 console.log("i can sing")
    16 }
    17 }
    18 NewTest.prototype=new Test();
    19 var children = new NewTest();
    20 children.sing();
    21 children.run();
    22 console.log(children.age);
    23
    24 console.log('----childre的属性----') ;
    25 for (var key in children){
    26 console.log(key) ;
    27 }
    28 //如果要过滤掉原型上的属性
    29 console.log('----childre的属性----') ;
    30 for (var key in children){
    31 if(children.hasOwnProperty(key)) {
    32 console.log(key);
    33 }
    34 }
    35 //所以对于一个对象的深拷贝
    36 var cloneObj={};
    37 for (var key in children){
    38 if(children.hasOwnProperty(key)) {
    39 cloneObj[key]=children[key]
    40 }
    41 }

     

    1. 同样也可以用递归的方法对对象进行深拷贝

       1 function deepCopy(obj,newObj) {
      2 newObj=newObj || {};
      3 for (var i in obj){
      4 if (typeof obj[i]==="object"){
      5 newObj[i]=obj[i].constructor===Array?[]:{};
      6 deepCopy(obj[i],newObj[i])
      7 }else {
      8 newObj[i]=obj[i]
      9 }
      10 }
      11 return newObj
      12 }

       

    和数组递归方式的深拷贝原理一样