-
資料型態
-
基本型別(Primitive type):
string, number, boolean, null, undefined, symbol-
複製行為: 直接複製原始值
-
Example:
let a = 4; let b = a; console.log(a); // 4 console.log(b); // 4 // 更改a值 a = 10; console.log(a); // 10 console.log(b); // 5
-
-
物件型別(Object):
object, array, funciton-
複製行為: 僅複製地址
-
Example:
let a = { number: 4 }; let b = a; console.log(a); // { number : 4 } console.log(b); // { number : 4 } // 更改a值 a.number = 10; // 因是物件因此是複製位置,所以改變的也是位置上的值 console.log(a); // { number : 10 } console.log(b); // { number : 10 } => 跟著 a 改變
-
-
-
基本型別與物件型別差異
- 儲存在記憶體中的方式不同
-
概念
- 傳遞變數時,是複製了傳遞進來的「值 (value)」
-
範例
-
概念:
- 傳遞參數時,僅是複製了參數的位置 (address)
-
範例
function referenceTest(objData) { objData.number = 10; // 改變物件內容 console.log(objData); // { number: 10 } } let a = { number: 5 }; // Object data referenceTest(a); console.log(a); // { number: 10 } => 跟著改變
-
概念:
- 類似於 call by value, 複製變數後也跟者複製變數真正的值
-
範例
function test(objectData) { objectData = { number: 10 }; // 物件重新賦值 console.log(objectData); // { number: 10 } } let a = { number: 5 }; // object data test(a); console.log(a); // { number: 5 }
- 說明:
- 是兩個完全獨立,每一層的資料地址都不同,相互不影響的深層物件
- 範例:
- JSON.stringify/parse
- Lodash cloneDeep()
- Recursive deepCopyFunction
-
說明:
- 有任何一層的資料地址相同,背後指向的值相同,兩個物件的操作會互相影響
-
範例:
-
直接複製
-
說明: original 與 clone 會互相影響
const originalData = { firstLayerNum: 10, obj: { secondLayerNum: 100, }, }; const clonedData = originalData; clonedData.firstLayerNum = 20; clonedData.obj.secondLayerNum = 200; console.log(originalData.firstLayerNum); // 20 => 第一層有被 clonedData 影響而改變 console.log(originalData.obj.secondLayerNum); // 200 => 第二層有被 clonedData 影響而改變
-
-
複製第一層物件
-
說明
function shadowCopy(originalObj) { let clonedObj = {}; for (const key in originalObj) { clonedObj[key] = originalObj[key]; } return clonedObj; } const originalData = { firstLayerNum: 10, obj: { secondLayerNum: 100, }, }; const clonedData = shadowCopy(originalData); clonedData.firstLayerNum = 20; clonedData.obj.secondLayerNum = 200; console.log(originalData.firstLayerNum); // 10 => 第一層沒有被 clonedData 影響 console.log(originalData.obj.secondLayerNum); // 200 => 第二層被 clonedData 影響而改變
-
-
Object.assign
-
說明
const originalData = { firstLayerNum: 10, obj: { secondLayerNum: 100, }, }; const clonedData = Object.assign({}, originalData); clonedData.firstLayerNum = 20; clonedData.obj.secondLayerNum = 200; console.log(originalData.firstLayerNum); // 10 => 第一層沒有被 clonedData 影響 console.log(originalData.obj.secondLayerNum); // 200 => 第二層被 clonedData 影響而改變
-
-
Spread operator
const originalData = { firstLayerNum: 10, obj: { secondLayerNum: 100, }, }; const clonedData = { ...originalData }; clonedData.firstLayerNum = 20; clonedData.obj.secondLayerNum = 200; console.log(originalData.firstLayerNum); // 10 => 第一層沒有被 clonedData 影響 console.log(originalData.obj.secondLayerNum); // 200 => 第二層被 clonedData 影響而改變
-
部分 Array 方法,如:slice()、from() 等
const originalData = [10, { secondLayerNum: 100 }]; const clonedData = originalData.slice(); clonedData[0] = 20; clonedData[1].secondLayerNum = 200; console.log(originalData[0]); // 10 => 第一層沒有被 clonedData 影響 console.log(originalData[1].secondLayerNum); // 200 => 第二層被 clonedData 影響而改變
-
