当前位置: 首页 > 資訊 >

Day 16 JavaScript boxing vs unboxing

boxing:

封裝可以讓原始型態的資料暫時轉成物件,這樣他才可以使用屬性或方法。
遇到使用字面值(literal)[註1]的原始型態資料後面接了一個方法時,JS 會自動幫他封裝(boxing),讓字面值能有屬性或方法可用。
但如果使用 new 去建立原始型態的資料,因為會建立出物件,所以就不會用到封裝了。

假設我宣告一個變數 a,將字串"abc"賦值給他,接著執行一個 substring 方法,照理說原始型態的資料不能使用屬性或方法才對,只有物件才能使用,所以這時候在 JS 就會發生 boxing。

boxing 會偷偷做以下三件事:

  1. 當 JS 發現 substring() 方法前面的 a 不是物件,他會自動用 new 這個運算符幫字串 "abc" 建立一個 b 物件。
  2. 因為 b 是物件,所以可以使用方法,接著讓 b 物件使用 substring() 方法。
  3. 用完後把 b 物件 給刪除,最後只留下原本的 a 常數。
const a = "abc"
a.substring()

ex:如果我想建立一個陣列出來分別可用兩種方式建立:

  • 用 literal 方式:let a = [ ]
    [ ] 就是一個符號,用來代表 array,把 a 指向 [ ]
  • 用正規方式:let a = new Array()
    用 new 會建立一個 a 物件,把 a 物件指向 [ ]

unboxing:

解封裝就是將他從物件轉回原始型態。
可以用 valueOf() 或是 toString()方法讓他轉回來。

// 建立一個 s 物件,指向字串'Hello World!'
const s = new String('Hello World!')
// 印出 s 的型態是 object
console.log(typeof s)
// 印出 s 的值的型態是 string
console.log(typeof(s.valueOf()))
// 直接把 s 從物件轉回字串,印出 string
console.log(typeof(s.toString()))

[註1]
literal:字面上的意思,用某種符號去代表那個東西。
{ }、[ ]、" "、' ' 都是 literal,分別代表物件、陣列以及字串。

參考:
[1]你懂 JavaScript 嗎?#7 原生功能(Natives)
[2]What is boxing and unboxing in JavaScript?
[3]JavaScript装箱及拆箱boxing及unBoxing用法解析