javascript对象克隆

克隆的概念

对象克隆,就是对一个对象生成一个一模一样的对象.但是在javascript中,使用简单的复制语句所实现的是原对象的一个引用,对其中任何一个对象属性方法的改变,都将会影响另一个的属性方法.
这里的对象不包括DOM对象,因为DOM对象有专用的clone()方法可用。

浅复制

浅复制(影子克隆): 仅仅复制所考虑的对象,而不复制它所引用的对象.
深复制(深度克隆): 深复制把要复制的对象所引用的对象都复制了一遍.
如何实现复制
浅复制:

//使用prototype原生属性.创建clone()方法
Object.prototype.clone=function(){
var newObj = new Object();
for(elements in this){
newObj[elements] = this[elements];
}
return newObj;
}
直接循环遍历原对象的属性赋值给新对象,但是这样的话,如果原对象属性中存在另一个对象的引用,那么就会造成复制不彻底.扩展一下文章开始的例子,不过这次稍微复杂一点,在对象中再插入一个对象.

//创建一个对象
var objOne = {
‘name’:'name1′,
‘info’:{‘identity’:'identity1′} //嵌套一个对象,这种工作中应该常用的
},
objTwo = objOne.clone(); //浅复制一个新对象
objTwo.name = ‘name2′; //重新赋值
alert(objOne.name); //name1
alert(objTwo.name); //name2
objTwo.info.identity = ‘identity2′; //改变identity的值
alert(objOne.info.identity); //identity2
alert(objTwo.info.identity); //identity2

当我们改变name属性值的时候,原对象的值没有改变,当我们改变克隆对象objTwo.info.identity=’PHPer’;时,原对象其值也发生了改变,这就是浅复制,不会去在乎原对象本身的引用.

深复制

深复制:
为了解决浅拷贝复制不彻底,所以就需要对原对象的引用对象也进行拷贝复制,采用递归实现.

Object.prototype.cloneAll=function(){
function clonePrototype(){}
clonePrototype.prototype = this;
var obj = new clonePrototype();
for(var ele in obj){
//如果检测到原对象中存在另一个对象的引用,那么递归,实现复制引用对象
if(typeof(obj[ele])==”object”)
obj[ele] = obj[ele].cloneAll();
}
return obj;
}
再回到刚才的例子:

//创建一个对象
var objOne = {
‘name’:'liangqi’,
‘info’:{‘identity’:'student’},
‘other’:[1,2,3]
},
objTwo = objOne.cloneAll(); //深复制一个新对象
objTwo.name = ‘godsee’; //重新赋值
alert(objOne.name); //name1
alert(objTwo.name); //name2
objTwo.info.identity = ‘identity2′; //改变identity的值
alert(objOne.info.identity); //identity1
alert(objTwo.info.identity); //identity2

通过深度复制,对原对象,以及原对象所有引用进行了复制,克隆了一个完全和原对象不相干的副本.

其他的实现:

Object.prototype.Clone = function(){
    var objClone;
    if (this.constructor == Object){
        objClone = new this.constructor(); 
    }else{
        objClone = new this.constructor(this.valueOf()); 
    }
    for(var key in this){
        if ( objClone[key] != this[key] ){ 
            if ( typeof(this[key]) == 'object' ){ 
                objClone[key] = this[key].Clone();
            }else{
                objClone[key] = this[key];
            }
        }
    }
    objClone.toString = this.toString;
    objClone.valueOf = this.valueOf;
    return objClone; 
} 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>