JS 原力覺醒 Day9 - 原始型別與物件型別

今天要講到 JS 型別概念,雖然你平常寫 JS 的時候可以看到很多種類別,但其實大致上可以分為兩個比較主要的大分類。

Outline

  • 物件型別 ( Object Type )
  • 原始型別(Primitive Type)

物件型別 ( Object Type )

第一種叫做「物件型別」,「物件」指的是物件。恩,但其實有很多東西本身也算是物件,例如陣列和函式,不相信嗎?讓我們繼續看下去,你可以再 JS 裡面宣告一個陣列,然後用 typeof 去得到這個陣列的型別,結果一定會讓你感到意外:

let arr = []  
console.log(typeof arr)  //object

那麽這樣我要怎麼判斷出陣列了呢? JS 提供了 Array.isArray() 的方法,來讓我們知道某物件是不是陣列。好,那麼函式也是物件型別嗎?當我一樣用 typeof 去觀察的時候,居然得到了不同的結果!

 let hello = function(){
	console.log('hello') 
} 
console.log(typeof hello) // function

「 看吧!聽你在亂講 」,你一定想這麼說,別急,換另一個方法來觀察看看, instanceof 是一個可以觀察某對象是不是另外一個對象的後代,那我們來看看 function 是不是物件的後代:

 console.log( hello instanceof Object ) // true

答案是沒錯。不過為什麼會這樣呢?函式在 JS 裡面算是一個比較特別的物件,稱為「 函式物件 ( Function Object ) 」,所以剛才我們用 typeof 乍看之下才會得到 function 的結果。 而正是因為「函式同時也是物件」這樣的特性,前面我們提到的「函式表達式 ( Function Expression ) 」才能成功!

let someVariable = function() {...} 

而函式物件特別的地方在於,只要搭配 new 關鍵字,他也能夠用來產生新的物件,這與其他物件導向語言產生物件的方法非常類似:

const Foo = function () {};
const bar = new Foo();
bar; // {}
bar instanceof Foo; // true
bar instanceof Object; // true

原始型別 ( Primitive Type )

原始型別又稱為純值 ( Primitive Type ) ,用來表示只代表單一值的一種資料型別,如 12 只代表12,沒有其他意思了,原始型別上也不像 物件型別上,有一些預設方法讓我們能夠直接取用,( Array.isArray )這樣子的東西,不像物件那麼複雜,所以稱為純值。此外,因為 JS 內只有兩種分類,所以「除了原始型別的型別,都是物件型別」,因此只要弄清楚哪些是原始型別,就可以很輕易找出物件型別。

JS 裡面有六種純值:

  • null
  • undefined
  • number ( 0 )
  • string ( “string”)
  • boolean ( true )
  • symbol (目前少用)

其中比較特別的純值是 ES6 之後才出現的 Symbol ,Symbol 類別是透過 Symbol () 方法產生,由於每個 Symbol 值所對到的記憶體位置不一樣,因此很適合用來避免物件屬性意外的被修改。

const a = {};
const symbol1 = Symbol('123');
const symbol2 = Symbol('123'); // they have different memory address in JS 
console.log(typeof symbol1);// expected output: "symbol"

a.symbol1 = 'Hello!';
a[symbol1] // undefined
a['symbol1'] // "Hello!"

上面可以看出使用字串來存取物件屬性跟以 Symbol 來存取會得到不同的結果,因為以往物件的屬性除了用 「.」運算子來存取,但這樣很容易因為重複赴值而被意外的修改,因此 Symbol 就可以用來避免這個問題發生。

" A symbol value may be used as an identifier for object properties; this is the data type’s only purpose. " - MDN Docs

結論

  1. Function 只是一種特殊型態的物件 (函式物件)
  2. Function 可以用來創造新的物件 (搭配 new 關鍵字)
  3. 不是所有的型別都是物件,但是除了純值以外的型別都是物件。
  4. JS 裡面有六種純值
  5. Symbol 可以用來防止物件屬性被意外的修改
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×