這次的內容是利用陣列跟物件做出深拷貝與淺拷貝
作品實做
淺拷貝:
指的是只複製物件的第一層,即只複製對象的引用。
如果物件中的屬性是原始類型(如字串、數字、布林值),它們會被完整地複製,不過如果屬性是物件或陣列,淺拷貝會複製它們的記憶體位置,而不是它們的內容。這樣,如果改變這些記憶體位置的屬性,原本的引用的內容也會被改變
深拷貝:
複製物件的每一層。所有的屬性(包括嵌套的物件或陣列)都會被完整地複製,沒有共享的引用。
const players = ["Wes", "Sarah", "Ryan", "Poppy"];
作者一開始給我們的預設陣列,接下來就開始運用方法來拷貝陣列吧!
1.擴展運算符(…)
可用於展開陣列、物件或可迭代物件的元素,而我們可以用它淺拷貝一個陣列
let players2 = [...players]; // ["Wes", "Sarah", "Ryan", "Poppy"];
而當重新賦值players2[0] =”tema”
,players
則不受影響,即我們已經成功複製了他的值(淺拷貝)
2.concat()
用來合併兩個或多個陣列。此方法不會改變現有的陣列,回傳一個包含呼叫者陣列本身的值,作為代替的是回傳一個新陣列。
let players3 = [].concat(players); // ["Wes", "Sarah", "Ryan", "Poppy"];
3.Array.prototype.slice()
會回傳一個新陣列,為原陣列選擇之[0]至 end(不含 end)部分的淺拷貝(shallow copy)。而原本的陣列將不會被改變。
let players4 = players.slice(); // ["Wes", "Sarah", "Ryan", "Poppy"];
4.Array.from(players)
可以將現有的陣列複製為一個新陣列,也可以將一個類似陣列的對象(如 likeArray)轉換為一個新的真正的陣列。
其實Array也有其他使用方式:例如可以將String拆解單字進一個array
let players5 = Array.from(players); // ["Wes", "Sarah", "Ryan", "Poppy"];
const person = {
name: "Wes Bos",
age: 80,
};
let person2 = Object.assign({}, person);
let person3 = { ...person };
※上面我們學到的擴展運算符(…)
也可用於淺拷貝物件資料
.Object.assign([], players)
可用來複製一個或多個物件,自己所有可數的屬性到另一個目標物件。回傳的值為該新的目標物件。
Object.assign(target, ...sources);// ["Wes", "Sarah", "Ryan", "Poppy"];
target
為合併的目標
...sources
為要合併的元素
接下來來實做看看:
let players6 = Object.assign([], players);// ["Wes", "Sarah", "Ryan", "Poppy"];
將players複製進一個空陣列,也可以達到淺拷貝的效果
JSON.parse(JSON.stringify(obj))
為物件先轉換為 JSON 字串,然後再解析回一個新的物件,從而實現深拷貝。
const wes = {
name: "Wes",
age: 100,
social: {
twitter: "@wesbos",
facebook: "wesbos.developer",
},
};
let wes1 = { ...wes };//**注意這為淺拷貝**
wes1["social"].twitter = "tema0105";
//我們物件內的物件沒有做到深拷貝 導致我們的做這行程式碼讓wes的值一併被改變了
let wes3 = JSON.parse(JSON.stringify(wes));
拿到控制台測試如果將wes3
屬性social.twitter改變數值,也不會改變原本wes物件內的數值,這代表我們成功做到了深拷貝
※雖然JSON.parse(JSON.stringify(obj))可以做到深拷貝,但當拷貝的內容裡有function時,無法拷貝到funtion,只會顯示其他原始類型以及物件跟陣列
[ Alex 宅幹嘛 ] 👨💻 深入淺出 Javascript30 快速導覽 | Day 14:JavaScript References VS Copying
JS30