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就是我们克隆的对象,改变它的值是不会对原有的对象产生影响的。这就是深度克隆!
浙公网安备 33010602011771号