zoukankan      html  css  js  c++  java
  • 克隆 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

        

  • 相关阅读:
    Mac系统访问Windows共享文件的详细步骤
    登录名 '***' 拥有一个或多个数据库。在删除该登录名之前,请更改相应数据库的所有者。 (Microsoft SQL Server,错误: 15174)
    窗口中文乱码,永久解决方法
    Delphi 快捷键列表
    Delphi代码规范
    hpwin10重置系统
    记:lr请求响应中文乱码转码方法!
    VMware NAT和桥接
    记:grafana不展示仪表盘数据解决方法
    性能的几个常见指标
  • 原文地址:https://www.cnblogs.com/adolfvicto/p/7490694.html
Copyright © 2011-2022 走看看