typeof
和instanceof
操作符都是用來判斷資料類型的,但是它們的使用場景卻各不相同,其中一些細節也需要特別注意。接下來讓我們一探究竟,徹底掌握該知識點,再也不懼面試官的提問。
typeof
是一個一元運算符,放在一個運算數前面,這個運算數可以是任何型別。它傳回一個字串,說明運算數的類型。請看栗子:
const type = typeof '中國萬歲'; // string typeof 666; // number typeof true; // boolean typeof undefined; // undefined typeof Symbol(); // symbol typeof 1n; // bigint typeof () => {}; // function typeof []; // object typeof {}; // object typeof new String('xxx'); // object typeof null; // object
透過以上例子可以看出, typeof
只能準確判斷基本資料型別與函數(函數其實是對象,不屬於另一種資料型別,但也能夠使用typeof 來區分),無法精確判斷出引用資料型態(統統返回object)。
有一點要注意,呼叫typeof null
回傳的是object
,這是因為特殊值null
被認為是一個對空物件的參考(也叫空物件指標)。
如果想準確判斷引用資料型,可以用instanceof
運算子。
instanceof
運算子放在一個運算數的後面,給定物件的前面。它傳回一個布林值,說明運算數是否是給定物件的實例:
const result = [] instanceof Array; // true const Person = function() {}; const p = new Person(); p instanceof Person; // true const message = new String('xxx'); message instanceof String; // true
typeof 會傳回一個運算數的基本型別,instanceof 傳回的是布林值
instanceof 可以精確判斷引用資料型,但無法正確判斷基本資料型別
typeof 雖然可以判斷基本資料型別(null 除外) ,但是無法判斷引用資料型別(function 除外)
typeof
和instanceof
都有一定的弊端,並不能滿足所有場景的需求。如果需要通用檢測資料類型,可以使用Object.prototype.toString.call()
方法:
Object.prototype.toString.call({}); // "[object Object]" Object.prototype.toString.call([]); // "[object Array]" Object.prototype.toString.call(666); // "[object Number]" Object.prototype.toString.call('xxx'); // "[object String]"
注意,該方法傳回的是一個格式為"[object Object]"
的字串。
為了更方便的使用,我們可以將這個方法進行封裝:
function getType(value) { let type = typeof value; if (type !== 'object') { // 如果是基本資料型,直接回傳return type; } // 如果是引用資料型,再進一步判斷,正規回傳結果return Object.prototype.toString.call(value).replace(/^[object (S+)]$/, '$1'); } getType(123); // number getType('xxx'); // string getType(() => {}); // function getType([]); // Array getType({}); // Object getType(null); // Null