從物件理解變數 / Immutable 觀念整理


Posted by yunanpan on 2020-06-19

整理 [JS101] 裡提到的〈從 Object 的等號真正的理解變數〉相關內容。


console.log([] === []) // false
console.log([1] === [1]) // false
console.log({} === {}) // false
console.log({a:1} === {a:1}) // false

上面的判斷式,兩邊長一樣,console.log 出來應該都會是 true,但為什麼結果全都是 false 呢?課程中是以記憶體位置不同的概念解說。我自己嘗試轉換成用不同形狀的容器養魚的方法去理解。

就算 {} === {} 等號兩邊的物件長得一樣,但只是魚缸裡的魚長一樣,但他們分別被養在不同形狀的魚缸(記憶體位置)裡,連同魚缸一起看魚的話,會發現兩邊其實是不同的,所以才會是 false。


情況一

var obj = {
    a: 1
}
var obj2 = obj
console.log(obj2 === obj) // true

當今天宣告一個物件 obj,再宣告另外的物件 obj2obj 時,就像是 objobj2一起用魚缸養魚,所以 obj2 會等同於 obj


情況二

var obj = {
    a: 1
}
var obj2 = obj
obj2.a = 2
console.log(obj2 === obj) // true

因為 objobj2 一起用魚缸養了魚,所以今天 obj2 在魚缸裡加東西,obj 也會跟著變,obj 還是等同於 obj2


情況三

var obj = {
    a: 1
}
var obj2 = obj
obj2 = {
    a: 1
}
console.log(obj2 === obj) // false

但當今天 obj2 給整個變數新的物件時(就算新的物件裡屬性和值都和 obj 一樣),就像是 obj2 拿了個新的魚缸養魚。所以 obj 就不同於 obj2了。


情況四

var a = 2
var b = a
b = 3
console.log(a === b) // false

而如果是 primitive type 的話,變數所宣告的值都是獨立的個體。所以儘管 b = a,但後續更動 b 的值跟 a 是無關的。



使用 function 注意事項

理解了前述的觀念,就可以理解 function 傳進 parameter 的運作機制:

function swap(a, b) {
    var temp = a
    a = b
    b = temp
}

var num1 = 10
var num2 = 20
console.log(num1, num2) // 10 20

swap(num1, num2)

console.log(num1,num2) // 10 20

因為丟到 function 裡的參數是複製一份的,所以儘管在 function 裡面數值確實有交換,但不會改變到外面的 num1num2 的值。


傳物件進 function 的情況

function addValue(obj) {
    obj = {
        number: 30
    }
    console.log('addValue', obj)
    return 1
}

var a = {
    number: 10
}

addValue(a)
console.log(a) // 11

而傳物件進去的情況,因為是放魚缸進去一起養魚,所以如果改變屬性,物件 a 的值會跟著改變。



Immutable 觀念

primitive type 的值是不可變的,所以今天要對原變數做什麼更動的話,都再賦一次值。

物件的話則有 mutator method 會更動到原陣列、原物件,所以使用的時候要注意。










Related Posts

[Day 04] 樣板模式,合成模式,狀態模式,代理模式

[Day 04] 樣板模式,合成模式,狀態模式,代理模式

MTR04_0818

MTR04_0818

自動化測試 x Puppeteer - 玩偶QA參一咖 Day01

自動化測試 x Puppeteer - 玩偶QA參一咖 Day01


Comments