Day.19 「認識 JavaScript 記憶體堆疊、傳值 與 傳址」 —— JavaScript 物件 與 記憶體
Day.19 「認識 JavaScript 記憶體堆疊、傳值 與 傳址」 —— JavaScript 物件 與 記憶體
我們的變數在我們開啟網站時,都會存放在記憶體內,當我們關閉網站時,記憶體也會將這些變數釋放。
記憶體的堆疊
JavaScript 變數都是保存在 Stack 中
Stack
而基本型別的值會直接儲存在 Stack 中,值與值之間獨立存在。
1 |
|
Heap
物件型別的值會保存在 Heap 中
每新增一個新物件(new Object),都會在 Heap 中開闢一個新空間。
而物件變數保存的會是指向新空間的地址(物件的引用複製),
如果新變數複製的是同一個物件,當一個物件屬性修改,另一個也會受到影響!
1 |
|
傳值(Pass by value)
所以根據上面的記憶裡內存,可以瞭解到單純的基本型別存入的就是單純的值。
而基本型別複製到別的變數,這個過程稱為傳值,複製過去後就是獨立的變數。
而變數的比較就是 Stack 值的比較,這比較簡單好懂。
1 |
|
傳址(Pass by reference)
而比較複雜的物件呢?上面也有看到物件存在 Stack 中的是 Heap 地址。
而物件型別複製到別的變數,這個過程稱為傳址,複製過去後,使用的都是同一個物件(地址)
而變數的比較是 Stack 值得比較,如果是新增物件的話,Stack 存入的地址會不一樣,所以會回傳 false
1 |
|
共享(Pass by sharing)
來囉!讓人頭昏昏眼花花的概念,物件遇上函式作用域就更加曖昧更加複雜了,上一篇認識了函式中的函式作用域,所以我們知道
當 參數 是 基本型別
傳基本型別的參數,其實就等於在函式作用域宣告變數並傳值,傳值獨立的關係,自然影響不到外面的變數,除非使用 return
回傳。
1 |
|
當 參數 是 物件型別
傳物件型別的參數,就變成在函式作用域宣告變數並傳址,傳址因為是引用同一個物件,所以對屬性更動時,就會影響到外面的物件變數!
1 |
|
沒錯!竟然修改了函式作用域外的東西了,因為指向的是同一個物件!
1 |
|
但如果是直接對整個物件修改,就會發現作用域外面不會被影響了,因為它等同於物件實字新增了一個新物件地址,這個值無法傳遞到外面。
總結
以上物件可以套用到陣列,這樣我們就認識物件型別與基本型別不同的地方了,有點抽象!傳值與傳址的概念在寫 JavaScript 邏輯時,非常重要,未來在學框架時,這些基礎越扎實,框架就學的越快越輕鬆!