
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; // truetypeof 會傳回一個運算數的基本型別,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