iT邦幫忙

0

2022 鐵人賽|Day5 【Javascript】const 失靈? 關於 Data types

Kim 2022-09-20 21:57:14563 瀏覽
  • 分享至 

  • xImage
  •  
附上為何鐵人賽文章會出現在這裡的說明:2022 鐵人賽|Day1 報名失敗,還是要開賽吧!

背景脈絡

不知道大家有沒有產生過這樣的疑問..

const person = {
    bodyHeight: 180,
    favColor: 'black'
};

person.favColor = 'blue';
console.log(person);  // print: {bodyHeight: 180, favColor: 'blue'}

。 為什麼裡面的值變了?
。 不是用 const 了嗎?
。 說好的宣告後不可更改的特性失靈了嗎?

今天學到的內容剛好替我解決的這樣的疑惑,原來跟 Data types 有關!以下整理~~


主題筆記

一、Data Types 分兩類

根據儲存位置不同,可以分成 Primitive Types & Reference Types(或者可以說 Primitives & Objects
Primitive Types 的值儲存在 Call Stack,而 Reference Types 的值儲存在 Heap

img

⬆️ 圖片來自於Jonas Schmedtmann的課程講義

二、Data Types 儲存方式

img

⬆️ 圖片來自於Jonas Schmedtmann的課程講義,下面解說(打完發現好長呀!希望有表達清楚)

.
Primitive Types

  1. 宣告age = 30,JS engine 會在 Call Stack 上創造一個 age identifier
  2. age identifier 指向存著「30」的「Stack memory address」
  3. 接著宣告oldAge = age,JS engine 會在 Call Stack 上創造 oldAge identifier
  4. oldAge identifier 指向與 age identifier 同一個 「Stack memory address」
  5. 接著重新為 age 賦值age = 31,已存在的 age identifier 會重新指向存著「31」的「Stack memory address」
  6. 所以 log 時,ageoldAge都有它們各自指向的值

.

Reference Types

  1. 宣告me = {...},JS engine 會在 Heap 創造出存著「物件值」的「Heap memory address」
  2. 然後 Call Stack 上會創造 me identifier
  3. me identifier 指向存著「Heap memory address值」的「Stack memory address」
  4. 而這個「Heap memory address值」會指向 Heap 中的 「Heap memory address」,進而對應到「物件值」
  5. 接著宣告friend = me,Call Stack 上會創造 friend identifier
  6. friend identifier 指向與 me identifier 同一個 「Stack memory address」,有著同樣的「Heap memory address值」指向 Heap 中的 「Heap memory address」,對應到同一個「物件值」
  7. 這時若對friend進行修改 ex.friend.age = 27,將會修改到 Heap 中的「物件值」
  8. 所以 console.log(me.age)時,也將會是 27, 因為mefriend是指向同一個「物件值」

三、const 沒有失靈!

理解兩種 Data Types 的儲存方式,就會發現用 const 宣告的 object(Reference Types),如果只是改變
object 中的值,它在 stack 中的指向確實沒有改變(都是存著「Heap memory address值」的「Stack memory address」)!但如果我們在宣告 object 後,重新賦值新的 object,就不行囉!

const me = {
  name: 'Kim',
  hobby: 'jogging',
};

me = {}; // Uncaught TypeError: Assignment to constant variable.

四、如何複製出新 object,而不是指向同一個?

使用Object.assign

⬇️ 合併兩個 object,創造新 object

const me = {
  name: 'Kim',
  hobby: 'jogging',
};

const newMe = Object.assign({}, me);
console.log(newMe); // print: {name: 'Kim', hobby: 'jogging'}

⬇️ 這兩個變數最終指向不同的「Heap memory address」

newMe.hobby = 'eating';
console.log(newMe); // {name: 'Kim', hobby: 'eating'} (newMe的hobby改變
console.log(me); // {name: 'Kim', hobby: 'jogging'}  (me的hobby沒變

參考資料

The Complete JavaScript Course 2022: From Zero to Expert! Unit 99 & 100


以上是今天的分享,謝謝看完的你!


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言