以前文章提到,在定义一个对象或数组时,变量存放的每每只是一个地址。当咱们对堆内存
中的对象复制时,若是属性是对象或数组时,这时候咱们拷贝的只是一个栈内存
的指针
。所以b对象在访问该属性时,会根据指针寻找到a对象指向的堆内存对象,二者的属性值会指向同一内存空间。数组
var a = { key1:"11111" } function Copy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } a.key2 = ['小辉','小辉']; var b = Copy(a); b.key3 = '33333'; alert(b.key1); //1111111 alert(b.key3); //33333 alert(a.key3); //undefined //对象中key1属性是字符串,key2属性是数组。a拷贝到b,12属性均顺利拷贝。给b对象新增一个字符串类型的属性key3时,b能正常修改,而a中无定义。说明子对象的key3(基本类型)并无关联到父对象中,因此undefined。 b.key2.push("大辉"); alert(b.key2); //小辉,小辉,大辉 alert(a.key2); //小辉,小辉,大辉
可是,若修改的属性变为对象或数组时,那么对象之间就会发生关联。从以上弹出结果可知,对b对象进行修改,a、b的key2
属性值(数组)均发生了改变。其在内存的状态,能够用下图来表示。spa
不但愿对象之间产生关联,那么这时候能够用到深拷贝。既然属性值类型是数组和或对象时只会传址,那么咱们就用递归来解决这个问题,把要复制的对象中全部属于对象的属性类型都遍历赋给新对象便可。指针
function Copy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; Copy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } a.key2 = ['小辉','小辉']; var b={}; b = Copy(a,b); b.key2.push("大辉"); alert(b.key2); //小辉,小辉,大辉 alert(a.key2); //小辉,小辉
过程以下图code