在 JavaScript 環境中,如果你輸入:
1 2
| console.log( [] == [] ); console.log( {} == {} );
|
兩個 log 得到的會是 true 還是 false ?
答案都是: false
再來看看其他例子
1 2 3 4 5 6
| var object1 = {value: 10}; var object2 = object1; var object3 = {value: 10};
console.log(object1 == object2); console.log(object1 == object3);
|
為什麼 object1 跟 object3 裡面的值一樣,卻不相等?
JavaScript 的 物件 與 一般變數 在存取時,是有不同的機制的,一般變數不論是 字串、Number、Boolean、Null…,變數在賦值時,指向的是它的 Value
,Value 相等比較出來結果也會相等,而 Object 就不同了,在宣告一個變數是 Object 或 Array 時,等於是創建了一個獨一無二的空間,拿兩個不同的空間比較,結果當然也就是 false
陣列也是 Pass By Reference
JavaScript 中,陣列也是物件的一種,同樣需要注意在複製、修改時,都必須要小心,看看幾個例子:
1 2 3 4 5 6
| let a = [1, 2, 3, 4]; let b = a; let c = [1, 2, 3, 4];
console.log(b === a); console.log(c === a);
|
那在 JavaScript 中陣列有什麼方法能 clone 呢?
- 使用
concat
,concat 是合併成一個新的陣列,不會修改到原本陣列
1 2 3 4
| let a = [1, 2, 3, 4]; let b = [].concat(a);
console.log(a === b)
|
1 2 3 4
| let a = [1, 2, 3, 4]; let b = [...a];
console.log(a === b)
|
Object 同樣也有方法能做到 clone
- 使用 Object.assign({}, Object)
1 2 3 4
| let a = {x: 1, y: 2, z: 3}; let b = Object.assign({}, a);
console.log(a === b)
|
1 2 3 4
| let a = {x: 1, y: 2, z: 3}; let b = {...a};
console.log(a === b)
|
- 但是在 Object 使用上面兩種方法還有一個大問題,如果 Object 裡面還有一層 Object 那會造成只有第一層被 clone 的情況,這種多層 Object 就不建議使用上面兩種方式,而是使用一個特殊的方法,JSON.parse(JSON.stringify),把 Object 轉成 JSON 字串,再轉回 JSON Object
1 2 3 4 5
| let a = {x: 1, y: 2, z: {i = 999}}; let b = JSON.parse(JSON.stringify(a));
console.log(a === b) console.log(a.z === b.z)
|
- 但是這也不是個完美的方法,如果 Object 很大一包 JSON.parse 和 JSON.stringify 是會造成效能問題的,所以使用時還是需要多加考量
Comments