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 }
原文地址:https://www.cnblogs.com/abcdecsf/p/12559678.html