關於 typeof 和資料型態

小知識。

簡述

在談 typeof 前,先來複習一下 JS 的資料型態。

JavaScript 裡的資料型態可以分成兩大類,一個是「Primitive」,一個是「Object」。

Primitive

  • String
  • Number
  • Boolean
  • undefined
  • null
  • symbol

Object

  • Object
  • Array
  • Function

最後也複習一下,Primitive 都屬於 Immutable(不可以改變)。

你不可能去改原本的值,除非你重新賦值。來看個例子:

1
2
3
const str = 'hello';
str.toUpperCase(); // 回傳一個新的字串
console.log(str); // 'hello' 還是原本的值

那 mutable 呢?最簡單的例子就是 Array

1
2
3
const arr = [1];
arr.push(2); // 這才是真的改變原本的值
console.log(arr); // [1, 2]

查看型態的方法

所以如果要看一個變數的資料型態,通常會用 typeof 來看:

1
2
3
console.log(typeof 'abc');  // string 
console.log(typeof 123); // number
console.log(typeof true) // boolean

可是有些案例比較特別,例如說 Array、Function 和 Null:

1
2
3
console.log(typeof []); // Object
console.log(typeof Function a () { return a}); // Function
console.log(typeof null); // Object

所以 typeof 沒有辦法很精準的檢查型態。網路有一張表有列出每個變數 typeof 的值是什麼,有興趣可以自己查。

那該怎麼解決呢?留到後面在告訴你,這邊先來看一下 null 這個特別的型態。

null 其實是個廣為人知的 Bug,沒有修正是怕改了很多東西會壞掉。而會有這 bug 是因為 JS 底層在實作 type 時會用「tag」來表示一個變數的型態。Object 的 tag 是 0,而 null 通常是用指標(0x00),所以就也被當成 0,得到 Object 的結果。

有沒有更嚴謹的檢查方式?

如果是 Array 的話,可以改用這個方法:

1
console.log(Array.isArray([])); // true

不過要注意,比較舊的瀏覽器不支援。

所以如果想更保險的話,可以用下面這個做法:

Object.prototype.toString.call(data)

1
2
3
4
5
6
// [object Number]
console.log(Object.prototype.toString.call(1));
// [object Array]
console.log(Object.prototype.toString.call([]));
// [object Null]
console.log(Object.prototype.toString.call(null));
檢查一個變數存不存在的正確方式 關於 NaN 這個東西
Your browser is out-of-date!

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

×