今天沒有畫面,而是要來認識在 JavaScript 中的傳值(拷貝)、傳址(參照)、淺拷貝。
深拷貝,傳值(Pass by Value)和傳址(Pass by Reference)是關於如何處理變數的兩種不同方式。此外,淺拷貝(Shallow Copy)和深拷貝(Deep Copy)也都是因為傳址而衍生的關於複製物件(陣列)時的兩種不同方法。我將用自己寫的例子來介紹這幾個名詞代表的意思及關係性。
傳值是指當你將一個原始資料類型(如數字、字串、布林值)賦值給另一個變數時,實際上是複製了原始值的內容。這樣,原始變數和新變數是獨立的,修改一個不會影響到另一個。
let a = 5;
let b = a; // 傳值
console.log(a, b); // 5 5
a = 10;
console.log(a, b); // 10 5
傳址是指當你將一個物件或陣列賦值給另一個變數時,實際上是傳遞了參考,而不是完全複製了一份內容。這表示原始變數和新變數都指向相同的物件或陣列,因此修改其中一個將影響到另一個,那麼我們要如何複製陣列或物件呢?這時候就需要用到下面的淺拷貝、深拷貝。
let arr1 = [1, 2, 3];
let arr2 = arr1; // 傳址
arr2.push(4);
console.log(arr1); // [1, 2, 3, 4]
console.log(arr2); // [1, 2, 3, 4]
淺拷貝是一種複製物件或陣列的方法,但它只複製了物件的第一層,內部的嵌套物件或陣列仍維持 Referencest 參照(傳址)。
let obj1 = { name: "Tim", hobbies: ["coding", "kpop"] };
let obj2 = { ...obj1 }; // 淺拷貝
obj2.hobbies.push("swimming");
console.log(obj1); // { name: 'Tim', hobbies: ['coding', 'kpop', 'swimming'] }
console.log(obj2); // { name: 'Tim', hobbies: ['coding', 'kpop', 'swimming'] }
淺拷貝Array的方式有:
const arr = [1, 2, 3];
const newArray = [...arr];
const arr = [1, 2, 3];
const newArray = Array.from(arr);
const arr = [1, 2, 3];
const newArray = arr.slice();
const arr = [1, 2, 3];
const newArray = [].concat(arr);
淺拷貝Object的方式有:
const obj = { name: "Tim", age: 28 };
const newObj = { ...obj };
const obj = { name: "Tim", age: 28 };
const newObj = Object.assign({}, obj);
深拷貝是一種複製物件的方法,它會複製整個物件,包括內部的嵌套物件或陣列,並且創建一個全新的物件,與原始物件完全獨立。要進行深拷貝的方式有
const obj = { name: "Tim", hobbies: ["coding", "kpop"] };
const newObj = JSON.parse(JSON.stringify(obj));
newObj.hobbies.push("swimming");
console.log(obj); // { name: 'Tim', hobbies: ['coding', 'kpop'] }
console.log(newObj); // { name: 'Tim', hobbies: ['coding', 'kpop', 'swimming'] }
const _ = require("lodash");
let obj = { name: "Tim", hobbies: ["coding", "kpop"] };
let newObj = _.cloneDeep(obj); // 深拷貝
newObj.hobbies.push("swimming");
console.log(obj); // { name: 'Tim', hobbies: ['coding', 'kpop'] }
console.log(newObj); // { name: 'Tim', hobbies: ['coding', 'kpop', 'swimming'] }
但是深拷貝可能會導致性能問題,特別是對於大型物件或陣列。因此,在選擇拷貝方式時,應根據實際需求來選擇淺拷貝或深拷貝。