淺談JS中物件的淺複製和深複製
基礎知識:
JS物件:指向記憶體中某個位置的指標,指標是可變的,也就是說可以被重新賦值,所以說,複製指標,只是將兩個指標指向記憶體中的同一地址,也可以說是地址複製。
//複製指標
var obj = { a: "123" };
var newObj = obj;
在上面程式碼中,物件 obj和 newObj都能隨著對方的變化而變化,所以要根據實際情況來複制物件。
一、淺複製
如果要操作的物件擁有的屬性都是值型別,那麼可以使用擴充套件語法或 Object.assign()
var obj = { foo: "foo", bar: "bar" };
var newObj = { ...obj }; // Object { foo: "foo", bar: "bar" }
var newObj = Object.assign({}, obj); // Object { foo: "foo", bar: "bar" }
補充知識:Object.assign()是ES6新加的介面,主要用來合併多個JS物件
- Object.assign() 第一個引數是目標物件,後面的都是源物件。 Object.assign (target, source1,source2, source3, …);
- 如果源物件與目標物件有相同的屬性名,或源物件中有相同的屬性名,後面的會覆蓋前邊的值
- 如果引數傳入的不是Object,會轉成Object
- null和undefined 不能作為引數傳入,因為null和undefined 不能轉成Object
- 如果發生的值是一個物件,Object.assign的處理方法是直接替換,而不是新增
Object.assign()內容詳情可檢視:MDN中對Object.assign()的描述
一個小細節注意一下:從使用效果上來看,Object.create()建立的新物件有點類似淺複製,只不過新物件和原物件是一種繼承關係,而Object.assign()建立的新物件和原物件是彼此獨立的。
var obj = { a: "123", b: { c: "321"}};
for(let p in obj){
newObj[p] = obj[p];
}
上述程式碼只進行了對物件第一層的複製,物件裡引用型別則進行的是地址複製,這一操作也是淺複製
二、深複製
1、有限制的深複製(先把物件序列化為字串,然後再將其反序列化)
var obj = { a: "123", b: "321"};
var newObj = JSON.parse(JSON.srtingify(obj));
限制:只在物件中包含可系列化值,且沒有迴圈引用的情況下使用
日期物件不可以被序列化,JSON.parse()後為字串而不是日期
2、限制較少的深複製(使用遞迴思想)
function deepCopy(obj){
var newObj = {};
for(let p in obj){
if(!(p instanceof object) || (typeof p === 'function)){
newObj[p] = objt[p];
}else{
newObj[p] = deepCopy(obj[p]);
}
}
return newObj;
}
所以可以得出一種較為通用的JS複製物件的方法:
function deepCopy(obj){
var newObj =obj.constructor === Array ? [] : {};
newObj.constructor = obj.constructor;
if(typeof obj !== 'object'){
return ;
}else if(window.JSON) { //若需考慮特殊資料型別,比如正則函式等,則去掉此else if
newObj = JSON.parse(JSON.stringify(obj));
}else {
for(let p in obj){
if(obj[p].constructor === regExp || obj[p].constructor === Date){
newObj[p] = obj[p];
}else if(typeof p === 'object'){
newObj[p] = deepCopy(obj[p]);
}else{
newObj[p] = obj[p];
}
}
}
return newObj;
}
學習參考:
https://segmentfault.com/a/1190000018903274#articleHeader1
https://baijiahao.baidu.com/s?id=1625060204489718788&wfr=spider&for=pc
這是我第一次寫學習總結文章,若有不對的地方,麻煩大佬們指出錯誤,我們共同進步呀~~
相關文章
- JS物件複製:深複製和淺複製JS物件
- 詳談Javascript中的深複製和淺複製JavaScript
- C#中的物件深複製和淺複製C#物件
- Java中物件的深複製和淺複製詳解Java物件
- JavaScript 淺複製和深複製JavaScript
- js 淺拷貝(淺複製、淺克隆)、深拷貝(深複製、深克隆)JS
- JavaScript中的淺複製與深複製JavaScript
- go slice深複製和淺複製Go
- python 深複製和淺複製Python
- 對於複製普通物件 深複製和淺複製是否一樣物件
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- js 淺複製和深複製的區別和應用JS
- Java引用複製、淺複製、深複製Java
- go的深複製跟淺複製Go
- Java 中的深複製和淺複製你瞭解嗎?Java
- python深複製和淺複製的區別Python
- c#淺複製與深複製C#
- python 淺複製、深複製坑Python
- 25. 深淺複製
- js物件深複製JS物件
- python 的深淺複製Python
- 【JavaScript】聊一聊js中的淺複製與深複製與手寫實現JavaScriptJS
- 淺顯直白的Python深複製與淺複製區別說明Python
- Python列表的深淺複製Python
- Day 7.5 資料型別總結 + 複製 淺複製 深複製資料型別
- js 實現深複製/深複製JS
- 資料共享(淺複製)與資料獨立(深複製)
- 聊一聊web前端那些事兒,關於深複製和淺複製Web前端
- Python中的賦值與淺複製與深複製之間的關係Python賦值
- 一文帶你瞭解js資料儲存及深複製(深拷貝)與淺複製(淺拷貝)JS
- 深入理解JavaScript之深淺複製JavaScript
- python 深/淺複製及其區別Python
- js 深複製JS
- JS 物件如何實現深複製JS物件
- 淺複製、深複製與序列化【初級Java必需理解的概念】Java
- Go 語言傳值和深淺複製問題Go
- 設計模式-原型模式(Prototype)【重點:淺複製與深複製】設計模式原型
- 淺談C#中的資料型別轉換與物件複製C#資料型別物件