以前文章提到,在定義一個對象或數組時,變量存放的每每只是一個地址。當咱們對堆內存
中的對象複製時,若是屬性是對象或數組時,這時候咱們拷貝的只是一個棧內存
的指針
。所以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