深度复制实例分析
javascript的一切实例都是对象,只是对象之间稍有不同,分为基本类型和引用类型。 基本类型对象指的是字符串(String)、数值(Number)、布尔值(Boolean),引用类型对象指的是数组(Array)、对象(Object)、函数(Function)。
这两类数据的引用有差别。普通对象存储的是对象的实际数据,而引用对象存储的是对象的引用地址,而把对象的实际内容单独存放,因为引用对象通常比较庞大,这是数据开销和内存开销优化的手段。 就像对象的原型一样,也是同一个概念。对象的原型也是引用对象,把原型的方法和属性放在单独内存当中,而对象的原型链则指向这个内存地址。
但有时我们需要的并不是指向内存区域的指针,而是内存中整个数据的备份(因为不想改动原数据)。不同的引用类型备份方法并不相同,于是我们可以对此封装了统一的深度复制接口。
1 function deepCopy(source) { 2 var result = {}; 3 for (var key in source) { 4 var type = Object.prototype.toString.call(source[key]); 5 switch (type) { 6 case "[object Number]": 7 case "[object String]": 8 result[key] = source[key]; 9 break; 10 case "[object Array]": 11 result[key] = source[key].slice(0); 12 break; 13 default: 14 result[key] = deepCopy(source[key]); 15 } 16 } 17 return result; 18 }
这里我们遍历了source对象的属性,使其劫持js对象原型的类型判别方法,当其是基本类型时直接赋值,是引用类型的数组类型时调用slice方法 截取整个数组(该方法返回的即时原数组备份),当其是其他对象时嵌套执行该函数。最终得到整个对象的备份。
基于jq的方法:$.extend(true,target,obj);
如果第一个参数设置为true,则jQuery返回一个深层次的副本,递归地复制找到的任何对象。否则的话,副本会与原对象共享结构。 未定义的属性将不会被复制,然而从对象的原型继承的属性将会被复制。
使用JSON解析为一个对象:var newobj=JSON.parse(JSON.stringify(sourceObj));