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

对于浅拷贝的理解

使用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 }

       

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

posted @ 2016-12-01 10:24  TJ-进无止境  阅读(1348)  评论(0编辑  收藏  举报