JS的深克隆

一、js中的对象

谈到对象的克隆,必定要说一下对象的概念。
 
js中的数据类型分为两大类:原始类型和对象类型。(1)原始类型包括:数值、字符串、布尔值、null、undefined(后两个是特殊的原始值,这里不做详细的说明,我的上一篇博客有谈到过一些)(2)对象类型包括:对象即是属性的集合,当然这里又两个特殊的对象----函数(js中的一等对象)、数组(键值的有序集合)。
 
好了既然对象分为这两类,这两种类型在复制克隆的时候是有很大区别的。原始类型存储的是对象的实际数据,而对象类型存储的是对象的引用地址(对象的实际内容单独存放,为了减少数据开销通常存放在内存中)。ps:说到这里,大家要知道,对象的原型也是引用对象,它把原型的方法和属性放在内存当中,通过原型链的方式来指向这个内存地址。
 
二、克隆的概念
浅度克隆:原始类型为值传递,对象类型仍为引用传递。
深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

三、浅克隆的表现

1,原始类型
看下面一段代码:
//数值克隆的表现
var a="1";
var b=a;
b="2";
console.log(a);// "1"
console.log(b);// "2"
 
//字符串克隆的表现
var c="1";
var d=c;
d="2";
console.log(c);// "1"
console.log(d);// "2"
 
//字符串克隆的表现
var x=true;
var y=x;
y=false;
console.log(x);// true
console.log(y);// false
从上面的代码大家可以看出,原始类型即使我们采用普通的克隆方式仍能得到正确的结果,原因就是原始类型存储的是对象的实际数据。
 
2.对象类型
前面说过,函数式一等对象,当然也是对象类型,但是函数的克隆通过浅克隆即可实现
var m=function(){alert(1);};
var n=m;
n=function(){alert(2);};
console.log(m());//1
console.log(n());//2
大家能看到,我们直接通过普通赋值的方式,就实现了函数的克隆,并且不会影响之前的对象。原因就是函数的克隆会在内存单独开辟一块空间,互不影响。
 
好了,说了这个特殊的”关系户“以后,我们来说说普通的”选手“。为了方便后续的代码表现,我这里定义一个复杂的对象类型oPerson。下面看一下对象类型的浅复制有什么危害:
 
复制代码
var oPerson={
    oName:"rookiebob",
    oAge:"18",
    oAddress:{
       province:"beijing"
    },    
    ofavorite:[
        "swimming",
        {reading:"history book"}
    ],
    skill:function(){
        console.log("bob is coding");
    }
};
function clone(obj){
    var result={};
    for(key in obj){
       result[key]=obj[key];
    }
    return result;
}
var oNew=clone(oPerson);
console.log(oPerson.oAddress.province);//beijing
oNew.oAddress.province="shanghai";
console.log(oPerson.oAddress.province);//shanghai
复制代码
通过上面的代码,大家能看到,经过对象克隆以后,我修改oNew的地址,发现原对象oPerson也被修改了。这说明对象的克隆不够彻底,那也就是说深度克隆失败!
 
四、深克隆的实现









你可能感兴趣的:(web前端)