zoukankan      html  css  js  c++  java
  • Javascript之 浅克隆 与 深克隆

      JS对象的浅克隆和深克隆,是我们可能会常用到的方法。对象克隆是指

      我们有一个对象A:

    A={
        name:"jack",
        hobby:['play','sleep'],
        son:{
            name:"jerry",
            hobby:['study','excercise']
        }
    }

      现在新建一个对象 var B={ },我们想把A对象的内容完完全全地拷贝到B当中去,用到的方法即为对象的克隆。

      在学习具体的实现方法之前,先要弄明白JS中的对象。在JS中,一切皆为对象,对象又可以分为两类,一类是不可改变的原始值(string number boolean undefined null)他们存储在"栈"中;另一类是引用值(array object  function )他们存储在"堆"中。

      在JS中,我们还要搞清楚值的传递: 传递原始值则仅仅传的是一个值,而传传递引用值传的是地址。eg :

     1 var a = 1;
     2 var b = a;
     3 a = 2;
     4 console.log(b); // 1
     5 
     6 var a = 'hello';
     7 var b = a;
     8 a = 'world';
     9 console.log(b); // hello
    10 
    11 var a = true;
    12 var b = a;
    13 a = false;
    14 console.log(b); // true

      通过以上代码不难发现,如果要克隆原始值,直接复制即可,且改变原始值的不会影响拷贝过来的数据。

      再来看引用值的克隆:

    var a = [1, 2, 3];
    var b = a;
    a.push(4);
    console.log(b); // [1, 2, 3, 4]

      这个时候,我们就发现,改变原数组,新的数组也会跟着变。那怎么才能不让他跟着变呢?

    浅克隆

      回到开头的对象A,

      我们现在通过浅克隆的方式把A克隆到B

    var B={
        name:A.name,
        hobby:B.hobby,
        son:B.son
    }

      封装为方法:

    function clone(origin,target){
        for(var prop in origin){
            target[prop]=origin[prop];
        }
        return target;
    }

      这就叫作浅克隆,但问题就是,原始值克隆过去是OK的,但引用值就麻烦了,改了一个,另一个就跟着变。

    深克隆

      既然要深克隆,我们就得通过嵌套遍历的方式,一个一个检查:

      B[0]:“你是原始值吗?”

      A[0] : “是”

      B[0]:“直接复制过来!”

      —————————————

      B[1]:“你是原始值吗?”

      A[1] :“不,我是引用值”

      “新建一个空对象(数组)!再继续往下追问” 

      —————————————

        B[1][0]:“你是原始值吗?”

        A[1][0] : “是”

        B[1][0]:“直接复制过来!”

        . . . . . .

      所以,在对象的深克隆方法中,显而易见的,我们要用到循环嵌套和递归的方法,具体分为以下5个步骤:

      1、遍历对象

      2、判断是不是原始值  for(var prop in obj)

      3、判断是数组还是对象  typeof() object

      4、建立相应的数组或对象  instanceof toString constructor

      5、递归,循环往复

      封装为方法:

     1 function deepClone(origin,target){
     2     for(var prop in origin){    //1、遍历对象
     3         if(origin.hasOwnProperty(prop)){
     4             if(origin[prop]!=="null"&&typeof(origin[prop])=='object'){  //2、判断是不是原始值
     5                 target[prop]=Object.prototype.toString.call(origin[prop])=="[object Array]" ? [] : {};  
                       //3、判断是数组还是对象4、建立相应的数组或对象 6 deepClone(origin[prop],target[prop]); //5、递归 7 }else{ 8 target[prop]=origin[prop]; 9 } 10 } 11 } 12 return target; 13 }
  • 相关阅读:
    ubuntu防火墙设置通过某端口
    pandas入门
    pyplot入门
    numpy教程
    跨域请求 spring boot
    spring boot 启动流程
    代理配置访问
    AOP,拦截器
    spring boot 启动不连接数据库
    Python 3.x 连接数据库(pymysql 方式)
  • 原文地址:https://www.cnblogs.com/abcdecsf/p/12559678.html
Copyright © 2011-2022 走看看