对象克隆

88 阅读2分钟

一、对象克隆的概念

对象克隆就是进行对象的复制,当一个对象完成之后实际上都会自动的开辟内存空间,在每一块堆内存空间里面都会保存有对象的相关属性内容,所谓的对象克隆所描述的就是属性的复制。

二、基本数据类型的赋值(String)

var a = "hello world";
var b = a;
console.log( b ); // 'hello world'
a = "c";
console.log( b ); // 'hello world'
// 把a赋值给b,当a的值发生变化时,并不影响b

三、引用数据类型的赋值(Array)

var arr1 = [1, 2, 3, 4];
var arr2 = arr1;
console.log( arr2 );  // [10, 2, 3, 4]
arr1[0] = 10;
console.log( arr2 );  // [10, 2, 3, 4]
// 把arr1赋值给arr2,当arr1的值改变时,arr2对应的值也会改变

注意

  1. 对于基本数据类型而言,把a的值赋值给b后,a的修改,不会影响到b。
  2. 对于引用数据类型而言,把arr1赋值给arr2后,arr1的修改,会影响到arr2对应的值
  3. 基本数据类型是直接存储在栈内存中的,而引用数据类型,则仅仅是把地址存储在栈内存中,真正的数据是存储在堆内存中的,赋值操作时,仅仅把地址进行了赋值。

四、深克隆和浅克隆

在实际的程序开发过程之中如果要想进行对象克隆的处理一般会有两种做法:深克隆和浅克隆。

对象是引用类型值

因为对象是引用类型值,所以不能用 var obj2 = obj1 这样的语法克隆一个对象。

使用 == 或 === 进行对象的比较时,比较的是他们是否为内存中的一个对象,而不是比较值是否相同

<script>
        // 例1
        var obj1 = {
            a:1,
            b:2,
            c:3
        };
        var obj2 = {
            a:1,
            b:2,
            c:3
        };

        console.log(obj1 == obj2); //false
        console.log(obj1 === obj2); //false

        // 空对象
        console.log({} == {});  //false
        console.log({} === {});  //false


        // 例2
        var obj3 = {
            a:10,
        };

        var obj4 = obj3;

        obj3.a++;

        console.log(obj4.a); //a:11
    </script>

1. 深克隆

所有与对象相关的引用类型全部进行克隆,而且对象的深克隆需要使用递归函数

function deepClone(o){
        // 分类判断类型值 
        // 判断o是对象还是数组 
    
    // Array的typeof值也是 object, 所以必须将遍历数组放在前面
    if (Array.isArray(o)){
        var result=[];
        for(var i=0; i<o.length;i++){
            result.push(deepClone(o[i])); 
        }
    } 
    
    else if (typeof o == 'object'){
        var result = {};
        for(var k in o){
            result[k]=deepClone(o[k]);
    }
   } 
   
   else{ 
       var result = o;
   }
       return result;
   }

2. 浅克隆

就是只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不进一步克隆他们,只传递它们的引用,使用 for...in...循环即可实现对象的浅克隆。

<script>
       var obj1 = {
        a:1,
        b:2,
        c:[44,55,66]
       }; 
       // 实现浅克隆
       var obj2 = {};
       // 每遍历一个k属性,就给obj2也添加一个同名的k属性
       // 值和obj1的k属性值相同 
       for(var k in obj1){
           obj2[k]=obj1[k];
       } 
       // 浅克隆不能将 引用类型值 完全分开
       obj1.c.push(77);
       console.log(obj2);
</script>