• 克隆 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

        

  • 相关阅读:
    VMWare安装win10提示units specified don’t exist, SHSUCDX can’t install
    WinXP.Http.Post请求错误提示:基础连接已经关闭:发送时发生错误
    如何用PostMan请求WebApi
    无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CI_AS_WS" 之间的排序规则冲突 解决
    c# Winform PropertyGrid 实现下拉框 多选
    c# Winform GridControl 给列自动生成快捷操作按钮
    Tomcat启动报内存溢出错误:java.lang.OutOfMemoryError: PermGen space异常 解决
    Net Core 项目引用Exceptionless记录使用
    .Net 开源异常日志ExceptionLess搭建
    c# AutoMapper 扩展
  • 原文地址:https://www.cnblogs.com/adolfvicto/p/7490694.html
Copyright © 2020-2023  润新知