發現此時newobj的number也變成了2,很顯然這不是我們想要的結果。往往我們開發專案中會大量用到賦值,卻發現之前原來的值也改變了。這時我們需要了解一下js到底是怎麼儲存這些變數的。var obj = ;
var newobj = obj;
console.log(newobj); //
obj.number = 2;
console.log(obj); //
console.log(newobj); //
在js中資料分為兩種型別,基本型別和引用型別,基本型別包括字串、數字、布林值、null、undefined,引用型別包括陣列、物件、正則。基本型別儲存在棧中,物件型別只能引用,引用如上obj則存在棧中,物件則儲存在堆中。當我們將obj賦值給newobj的時候,我們只是將obj儲存在堆中的引用賦給了newobj,而他們指向堆記憶體中同乙個資料。所以我們修改了物件obj存在堆中的資料後,同樣引用同一資料的物件newobj也發生了改變。
所以有人會問了,剛才我們進行的賦值操作是什麼呢?其實就是js的淺拷貝。下面就來分別實現一下淺拷貝和深拷貝。
1、使用es6擴充套件運算子(...)
2、使用object.assignvar obj = ;
var newobj = ;
3、陣列可以使用slice和concatvar obj = ;
var newobj = object.assign({}, obj);
obj.number = 2;
console.log(obj) //
console.log(newobj); //
這兩個陣列方法都會產生新的陣列,並且不改變原陣列,可以參考我的個人部落格js 陣列的基本運算,當然你使用map,reduce 等方法產生陣列也可以,相比較上面兩個方法會顯得比較複雜var arr = [1, 2, 3];
var arr1 = arr.slice();
var arr2 = arr.concat();
4、使用jquery的extend方法
1、使用遞迴方法var arr = [1, 2, 3, 4];
var newarr = $.extend(, arr);
先看下遍歷物件有哪些方式
2、使用json.stringify和json.parse實現function deepcopy(obj) else if(tostring.call(obj) === '[object regexp]') else if(tostring.call(obj) === '[object array]') )
} else ;
reflect.ownkeys(obj).foreach(key => )
}} else
return res;
}var obj = ,
b: function () {},
c: [
},'c',
null]}
var obj1 = deepcopy(obj);
json.stringify把物件轉成字串,再用json.parse把字串轉成新的物件。當然有明顯的缺陷,像map, set, regexp, date, arraybuffer、undefined、函式等json.stringify無法轉義。var obj = ,d:{}};
var obj1 = json.parse(json.stringify(obj));
obj.a.b.c = 3;
console.log(obj1.b.c); // 2
3、通過jquery的extend方法實現深拷貝
4、lodash函式中的clonedeep()實現深拷貝var obj = ,d:{}};
var newobj = $.extend(true,,obj);
含有大量的內建型別處理,細節處理很不錯。原始碼點這
js實現深拷貝
深拷貝 深拷貝本身只針對較為複雜的object型別資料,但是含義的話比如基本資料型別a和b的賦值操作,賦值之後b有自己的記憶體空間,a,b之間互不影響 淺拷貝 引用資料型別 名存在棧記憶體中,值存在於堆記憶體中,但是棧記憶體會提供乙個引用的位址指向堆記憶體中的值。當b a進行拷貝時,其實複製的是a的...
JS 深拷貝實現
web平台上一直在刻意的避開深拷貝,一直使用json.parse json.stringify object 避開深拷貝的問題。知道今天碰見個bug,json將function轉化為了字串,排到這個bug時,憔悴 若是node.js平台的話,一直現成的輪子等著挑,可惜是web,不太敢亂引入,手寫乙個...
JS實現深拷貝
缺點 1 如果物件裡有函式,函式無法被拷貝下來 2 無法拷貝copyobj物件原型鏈上的屬性和方法 3 當資料的層次很深,會棧溢位 function deepcopy source 陣列相容 for var k in source else return target function isobje...