一、場景
除了基本類型跟null,對象之間的賦值,只是將地址指向同一個,而不是真正意義上的拷貝
將一個對象賦值給另外一個對象。
var a = [1,2,3]; var b = a; b.push(4); // b中添加了一個4 alert(a); // a變成了[1,2,3,4]
自定義對象
var obj = {a:10}; var obj2 = obj; obj2.a = 20; // obj2.a改變了, alert(obj.a); // 20,obj的a跟着改變
這就是由於對象類型直接賦值,只是將引用指向同一個地址,導致修改了obj會導致obj2也被修改
二、淺拷貝
所以,我們需要封裝一個函數,來對對象進行拷貝,通過for in 循環獲取基本類型,賦值每一個基本類型,才能真正意義上的復制一個對象
var obj = {a:10}; function copy(obj){ var newobj = {}; for ( var attr in obj) { newobj[attr] = obj[attr]; } return newobj; } var obj2 = copy(obj); obj2.a = 20; alert(obj.a); //10
這樣就解決了對象賦值的問題。
三、深拷貝
但是這里存在隱患,如果obj中,a的值不是10,而是一個對象,這樣就會導致在for in中,將a這個對象的引用賦值為新對象,導致存在對象引用的問題。
var obj = {a:{b:10}}; function copy(obj){ var newobj = {}; for ( var attr in obj) { newobj[attr] = obj[attr]; } return newobj; } var obj2 = copy(obj); obj2.a.b = 20; alert(obj.a.b); //20
因此,由於這個copy對象只是對第一層進行拷貝,無法拷貝深層的對象,這個copy為淺拷貝,我們需要通過遞歸,來拷貝深層的對象。將copy改造成遞歸即可
var obj = {a:{b:10}}; function deepCopy(obj){ if(typeof obj != 'object'){ return obj; } var newobj = {}; for ( var attr in obj) { newobj[attr] = deepCopy(obj[attr]); } return newobj; } var obj2 = deepCopy(obj); obj2.a.b = 20; alert(obj.a.b); //10