因為 JavaScript 是動態型別語言,變數的型別可以隨時改變,如果沒有型別檢查,很容易發生隱性的錯誤。正確判斷資料型別對於避免錯誤實在是太重要。在 JavaScript 中有很多種判斷資料型別的方法,各自用法都不大相同,本篇文章將詳細講解各種方法,並解析這些方法的常見陷阱,避免踩雷!!
JavaScript 的資料型別
JavaScript 的資料型別分為 Primitive(原始型別)與 Object(物件型別),除了七種 Primitive 之外,其他所有值本質上都是 Object。
原生值
- string
- number
- boolean
- undefined
- null
- symbol
- bigint
物件
除了上述七個資料型別,其他像是 function、array、date 等都是物件。關於 JS 中的詳細資料型別可參考:【JavaScript 入門:資料型別一次搞懂! Primitive 與 Object 的差異】
typeof 運算子
最常用的型別判斷方法就是 typeof ,typeof 是一個運算子,會返回一個代表資料型別的字串。
typeof 基本上可以判別上述提到的七個原生值與一個物件,但是! typeof 有幾個例外
例外一:primitive 的 null
console.log(typeof null); // object
關於 null 會被 typeof 判斷為 object 似乎是個歷史遺留的問題,據說因為修復成本太高所以一直擺著沒有修XD
其他 primitive
console.log(typeof "Hello"); // string
console.log(typeof 123 ); // number
console.log(typeof true); // boolean
console.log(typeof undefined ); // undefined
console.log(typeof 10n); // bigint
console.log(typeof Symbol()); // symbol
例外二:object 的 function
console.log(typeof function func(){}); // function
function 是唯一一個「object 卻會回傳 function」的例外。
其他 object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof new Date); // object
console.log(typeof new RegExp); // object
判斷陣列
前面提到,所有的 *object* 用 typeof 判斷都會輸出「object」,如果想要判斷一個物件是不是陣列的話,可以用 Array.isArray(value) 方法。
範例
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
判斷物件種類
我們可以透過 instanceof 這個運算子判斷一個變數是否為特定物件,概念和 typeof 有點像,但是僅限用於 object !!
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new RegExp instanceof RegExp);// true
console.log(new Date instanceof Date); // true
console.log("str" instanceof String); // false,不能判斷 primitive
- 上面的 "str" 會判斷 false 是因為他不是用
new String("str")建立的,如果用new建立一個這樣的「物件」,就會讓輸出結果完全不同!
還有一點要注意,其實 instanceof 有一個小陷阱,就是「幾乎所有物件都會 instanceof Object」,因為他們都是繼承自 Object。
這段內容攸關原型 (Prototype) 與原型鏈 (Prototype Chain) 的概念,以後有機會再寫一篇相關文章 ><
console.log([] instanceof Object); // true
console.log(new Date instanceof Object); // true
萬用判斷方法
那如果真的很想要準確判斷這個值到底是誰! 是number、boolean、 array、object 還是 function,就可以用 Object.prototype.toString.call(value) 判斷。
範例
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(1)); // [object Number]
console.log(Object.prototype.toString.call("str")); // [object String]
console.log(Object.prototype.toString.call([1,2])); // [object Array]
console.log(Object.prototype.toString.call({a:3})); // [object Object]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
總結
JavaScript 的判斷資料型別看似簡單,實則不簡單,其實隱藏著不少細節與陷阱。由於 JavaScript 是動態型別語言,變數的型別可以隨時改變,因此在實務開發中做好型別判斷,是避免隱性錯誤的重要關鍵。
快速總結一下本篇的重點:
- 想快速判斷基本型別,用
typeof - 想判斷陣列,用
Array.isArray() - 想確認物件類型,用
instanceof - 想要最精準結果,用
Object.prototype.toString.call()
相較於 typeof 與 instanceof,Object.prototype.toString.call() 是最穩定且最精準的型別判斷方式(雖然很長一句但是讚)。
參考













