Javascript深度克隆与深度赋值

在前端开发中、我们经常会碰到需要克隆(复制)js对象的时候。如下:

var p = { name: "张三", shade: { width: 1, height: 20} };

function clic()
{

   var newP =p;
   newP.shade.width=100;
   alert(newP.shade.width);

alert(p.shade.width);
}

 上面代码通常是要复制一个P的对象,而用“=”这样的操作,实际是那个是对象的引用,当我们改变了shade.width值时,P值也跟随变化了,这不是我们想要的。Jquery貌似出了一个深度克隆的方法,下面我们就来看下深度克隆是如何实现的。直接上代码了。

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();
        else
            obj[ele] = obj[ele];
    }
    return obj;
};

 上面代码前2行,首先声明了一个clonePrototype的对象,注意:这里我们把clonePrototype看作是一个对象,记住,javascript一切皆为对象。然后把它的原型扩展交给了this,this则是Object的原型扩展cloneAll。

下面才是真正用到clonePrototype,obj=new clonePrototype(); new 了一个clonePrototype对象的实例,接着循环obj的属性,此时:obj相当于Object扩展的原型实例,假设调用为   {name:"张三",shade:{width:1}}.cloneAll(); 此时的object 就相当于{name:"张三"}。 接着看下面,判断了每个属性的类型,如果不为object 那么则可以直接赋值。

重点我们看if语句块条件成功时执行的代码: obj[ele] = obj[ele].cloneAll();  这句代码看起来有点难懂,但是仔细理解还是没什么难度的。 obj[ele] 就相当于{name:"张三",shade:{width:1}}里的shade 部分,因为name部分不为object类型。那后面的obj[ele].cloneAll()又是在干嘛呢,实际上这里obj[ele]是一个对象,而我们的代码就是给对象克隆的扩展,所以当前这个对象的对象同样是可以扩展的,执行到这里时如果在扩展第一行下断点的话,它应该是会执行到第一行的语句块里,而不会到return 的地方,这相当于调用了自身,只要当前的《属性为对象》,(shade 实际上是整个{name:"张三",shade:{width:1}}的一个属性) 那么代码就继续往深层进行复制,最终会返回给我们一个新的obj,这个obj就是我们克隆的对象,改变它的值是不会对原有的对象产生影响的。这就是深度克隆!

 

posted on 2014-10-31 09:26  寒_飞  阅读(1860)  评论(0)    收藏  举报

导航