JavaScript基础-----数组&对象的深度clone

1.数组的浅克隆:

var arr = [1,2,3];     //引用类型
var arr1 = arr;
console.log(arr == arr1);   //true,进行比较时,比较的是地址
arr1.push(6);	
console.log(arr == arr1)     //true
console.log(arr,arr1)       //二者都输出[1,2,3,6]

    结论:这个方式只是简单的复制了原数组,地址不会改变,当改变它们的任意一个数组时,它们都会发生改变;

    针对以上出现的情况,有下列几种克隆的方式(以上面 arr 数组为例);

    (1)使用数组的 concat() 方法

var arr2 = arr.concat();
console.log(arr == arr2);    //false,说明它们的地址不相同
console.log(arr2);        //[1,2,3],只是简单的复制 
arr2.push(5);
console.log(arr,arr2)       //输出[1, 2, 3]和[1, 2, 3, 5],原数组没有发生改变,说明克隆成功

    (2)重新创建一个空的数组,进行遍历赋值:

var arr3 = [];
for(var i = 0;i < arr.length;i ++){
     arr3.push(arr[i]);    
     arr3[i] = arr[i];    //也可以这样写
}
console.log(arr == arr3);    //false
arr3.unshift(6);
console.log(arr,arr3)     //输出[1, 2, 3]和[6, 1, 2, 3],原数组没有改变,克隆成功
    (3) ES6中的 Array.from() 方法:
var arr4 = Array.from(arr);
console.log(arr == arr4)    //false
arr4[2] = "ha"
console.log(arr,arr4)     //输出[1, 2, 3]和[1, 2, "ha"],克隆成功

    (4)ES6中的超引用(...)方式:

var arr5 = [...arr];
console.log(arr == arr5)   //false
arr5.pop();
console.log(arr,arr5)     //输出[1, 2, 3]和[1, 2],克隆成功

2.对象的浅克隆:

    对象的同数组一样,都是引用类型,比较时也是比较地址,下面通过一个例子,列出对象的几种克隆方式:

var obj = {
    a : 1,
    b : "3",
}

    (1)重新创建一个空对象,进行遍历赋值:

var obj1 = {};
for(var key in obj){      
    obj1[key] = obj[key]
}
console.log(obj == obj1);    //false
obj1.c = "5";
console.log(obj,obj1)      //输出{a: 1, b: "3"}和{a: 1, b: "3", c: "5"},克隆成功

    (2)ES6中的超引用(...)方式(同数组):

var obj2 = {...obj}
console.log(obj == obj2)    //false
obj2.b = "hello";
console.log(obj,obj2)     //输出{a: 1, b: "3"}和{a: 1, b: "hello"},克隆成功

3.数组&对象的深度克隆

    以上数组&对象的克隆仅仅是针对于纯数组或纯对象,当出现数组&对象中的元素也为对象或数组时,用以上方式就会克隆失败,以下列数组代码为例,列出两种深度克隆的方式;

var num = [1,2,["a","b"],{e:"3"}];

    (1)最简单的方式,使用json序列化的方式

var num1 =
JSON.parse(JSON.stringify(num));        //注意json书写格式
console.log(num == num1)       //false
num1[2].push("c");
num1[3].e = 5;
console.log(num)      //输出[1,2,["a","b"],{e:"3"}]
console.log(num1)     //输出[1,2,["a","b","c"],{e:5}] ,克隆成功

    (2)封装一个函数,克隆所有对象的方式

function clone(obj){
   var newObj;
   if(typeof newObj = "object"){
        if(obj === null){
            newObj = null;
        }else{
            if(obj instanceof Array){         //判断obj的原型是否为Array,是返回true,否则返回false
                 newObj = [];        //数组
                 for(var i = 0;i < obj.length;i ++){
                     newObj.push(clone(obj[i]));
                 }
            }else{
                 newObj = {};       //对象
                 for(var j in obj){
                     newObj[j] = clone(obj[j])
                 }
            }
        }
   }else{
       newObj = obj;
   }
   return newObj;
}

//调用这个函数
var num2 = clone(num);
console.log(num == num2);      //false
num2[2].shift();
num2[3].f = "hello";
console.log(num);       //输出[1,2,["a","b"],{e:"3"}]
console.log(num2)       //输出[1,2,["b"],{e:"3",f:"hello"}],克隆成功


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值