克隆 JS克隆

  很多时候,当我们定义一个js数组或是对象的时候,上文对其进行了操作,下文又需要使用原来的对象,这时便想到

复制一个新的对象,且看下面的操作:

  function copy(parent,child){

    var child = child || {};//如果没有则创建一个

    for(var i in parent){

      if(parent.hasOwnProperty(i)){//判断parent中的属性是不是自有属性

        child[i] = parent[i];

      }

    }  

    return child;

  }

  调用一下我们定义的此函数:

  var father = {name:'st'};

  var son = copy(father);

  console.log(son.name);//输出结果为:'st';

  上述代码可以简单实现复制,但是,这种方法只实现了‘浅克隆’,也就是说,如果当前克隆的父对象中含有的子属性正好

也是一个对象,那么,当我们操作克隆出来的新对象的时候,如果新对象的子对象被修改,原先被克隆的父对象此时也被进行

了修改,这并不是我们想要的结果!请看下例:

  var  father = {

    wife:[1,2,3,4],

    car:{

      lamborghini:true

    }

  }

  var son = copy(father);

  console.log(son);//此处输出和father一样;

  如果我们此时对son的属性进行修改:

  son.wife.push(666);
  son.car.lamborghini = false;

  console.log(son.wife);//[1,2,3,4,666];

  console.log(son.car);//lamborghini:false;

  再打印出father对象,如下图所示

   

   可以看出,改变了son,父对象father也被改变了,这显然不是我们的初衷!因为对象是通过引用传递的,即father.wife和son.wife指向的是同一个数组;

  要想实现我们想要的功能,需要对copy函数加以改造,我们遍历father的属性时,如果是对象,则递归复制该对象属性!

    

  function copyDeep(parent,child){

    var child = child || {};//如果没有则创建一个

    for(var i in parent){

      if(parent.hasOwnProperty(i)){//判断parent中的属性是不是自有属性

        if(typeof parent[i] == 'object'){//判断parent属性是否为对象

          //此处需要判断该对象是不是数组,因为二者的创建方式有差异

          child[i] = (Object.prototype.toString.call(parent[i]) === "[object Array]") ? [] : {};//**此句将在文章后介绍(检查胎记

          copyDeep(parent[i],child[i]);

        }else{

          child[i] = parent[i];

        }

      }

    }  

    return child;

  }

  来看看效果如何:

  var father = {

    wife:[1,2,3,4],

    car:{

      lamborghini:true

    }

  }

  var son = copyDeep(father);

  

 此时我们再打印出father

  

  look !! !还是原来的味道。大功告成!

 大家都知道,上述代码使用了递归,递归的执行效率比较低!那么既然这么说了,肯定有另外一种的方法咯!

 请看:

  function copyDeep(parent,child){

    var temp;

    temp = JSON.stringify(parent);

    temp = JSON.parse(temp);

    var child = child || {};//如果没有则创建一个

    for(var i in temp){

      if(temp.hasOwnProperty(i)){//判断parent中的属性是不是自有属性

        child[i] = temp[i];

      }

    }  

    temp = null;

    return child;

  }

  调用后效果和递归实现的效果一致;

  /***********************/

  上述参考原文:http://www.jb51.net/article/79707.htm,作出的总结笔记!

  /**********************/

  关于上述文章中黄色背景处的解释,此处不作为本文重点!!

    详情解释见上片文章:http://www.cnblogs.com/adolfvicto/p/7490891.html

 

 

    

 

posted @ 2017-09-07 17:35  adolfvicto  阅读(226)  评论(0编辑  收藏  举报