JS基礎:Primitive type v.s Object types

LeeBoy
4 min readMar 10, 2017

--

本文參考:JavaScript: The Definitive Guide 6th

在 JS 世界,跟其他許多程式語言一樣,大致上有幾種方式處理變數

  • copy 複製
  • pass 傳值
  • compare 比較
  • mutate 變更

而 JS 的型別,主要有兩種

  • Primitive type 原始型別
  • Object types 物件,国人稱之為対象

TLDR 先講結論

Primitive types are manipulated by value and object types are manipulated by reference.

— 原始型別處理值,物件型別處理參考

接著將從這兩型別討論各種處理變數的方式

Primitive type 原始型別

primitive type by value 去處理,在 js 有以下成員

  • String
  • Number
  • Boolean
  • Null
  • Undefined

何謂 by value 呢?舉例來說,當宣告一個新變數 y並 assign 原變數 xy 時,y 的值是複製 x 值來的,所以之後當 y 值做任何變動都不會影響到x

let x = 2// Copy by value
let y = x
y += 5
console.log(y, x)
// 7, 2

除了複製,當 x y 兩者互相比較時,也是以真實的值互相比較的。

最後是傳值,當把 x y 作為參數傳入某 function 時,也是複製另外兩個新變數,在傳入某 function ,所以不管在 function 裡做任何操作都不會影響原本的 x y

String

字串比較特別,還有一個特色叫 immutable ,當使用String.prototype methods做任何操作都不會影響到原字串,

let s = 'macbook's.toUpperCase()s.slice(-4)s.concat('pro')s[3] = 'r'console.log(s)  // still log 'macbook'

而字串的比較,只有在 (if and only if) 長度相同且索引位置上位元相等時,兩者才相等。

Object type 物件型別

objective type by reference 去處理,一般來說在 js 以下屬於此類

  • Object
  • Function
  • Array
  • Set

其實幾乎任何型別在 javascript 都可以是 object (除了nullundefined),有興趣可以參考以下影片,

‘almost’ everything in Js is an Object

by reference 指的是當物件型別在操作時,其實底層是對實體記憶體為製作操作,當宣告一新變數 arr2 並將 arr1 賦值給 arr2時,其實是把記憶體位置給 arr2 所以任何對 arr2 的操作都會連動到原本 arr1 的值

by reference

值得注意的是,宣告兩個 objective type 讓 key-value 值完全相同,但是兩者比較後,回傳是 false ,因為 by reference 在比較時,真正比的是兩者的位置,所以個別的 Array 、Object 永遠不會相同。

Object type copy

那如果要複製 objective type 字面值,而不是參考位置具體該如何操作呢?以下分別就 Array 和 Object 分別舉例示意,

  • Array
  • Object
註:Object Spread syntax 本文撰寫時尚未支援

⚠️ 當Object裡面有巢狀結構時,用上述的複製方法能是屬於 by reference

可以參考以下方法,但可能效能有點差 (*詳見參考資料)

const Batman_Beyond = JSON.parse(JSON.stringify(Batman))

📚參考資料

  1. JavaScript: The Definitive Guide
  2. Spread operator vs Object.assign
  3. Deep Copy vs JSON Stringify / JSON Parse

--

--

LeeBoy

I’m rebuilding my life by discovering who I am, learning what I’m capable of after US.