相信一提到怎麼判斷js的數據類型,你們都會想到的是typeof、instanceof,那麼爲何有了typeof的存在還要有instanceof?git
根據MDN:typeof操做符返回一個字符串,表示未經計算的操做數的類型。github
eg:面試
typeof 1; // 'number'
typeof NaN; // 'number'
typeof 'zenquan'; // 'string'
typeof true; // 'boolean'
typeof null; // 'object'
typeof undefined; // 'undefined'
typeof Symbol(); // 'symbol'
typeof console.log // "function"
複製代碼
typeof出現的問題1——typeof null === 'object'數組
而後你會發現,typeof null; // 'object'
。null但是原始數據類型的啊,怎麼就是'object'了呢??(不解.jpg)原來這個已是歷史問題了,在 JS 的最第一版本中使用的是 32 位系統,爲了性能考慮使用低位存儲變量的類型信息,000
開頭表明是對象,然而 null
表示爲全零,因此將它錯誤的判斷爲 object
。雖然如今的內部類型判斷代碼已經改變了,可是對於這個 Bug 倒是一直流傳下來。函數
typeof出現的問題2——typeof 引用類型 || Math === ‘object’性能
這樣根本不知道是數組仍是對象測試
typeof [] // "object"
typeof {} // "object"
複製代碼
typeof出現的問題3——typeof 基本包裝類型 || Array ||Date === ‘funtion’ui
這樣也不能知道是Number仍是Boolean仍是Stringspa
typeof Number // "function"
typeof Boolean // "function"
typeof String // "function"
複製代碼
由於typeof有了以上的問題,因此纔有了instanceof。prototype
根據MDN:instanceof運算符用於測試構造函數的prototype屬性是否出如今對象的原型鏈中的任何位置
也就是 p instaceof person === true,則p是person的實例化對象,用於包裝對象或者是引用類型對象的判斷。
var str1 = 'zenquan';
console.log(str1 instanceof String); // false
var str2 = new String('jomsou');
console.log(str2 instanceof String); // true
複製代碼
可能會出現的面試題: 如何判斷一個數組?
方法1: instanceof
arr instanceof Array
複製代碼
方法2: Array.isArray()
Array.isArray([])
複製代碼
class PrimitiveString {
static [Symbol.hasInstance](x) {
return typeof(x) == 'string';
}
}
console.log('hello world' instanceof PrimitiveString);
複製代碼
你可能不知道
Symbol.hasInstance
是什麼東西,其實就是一個能讓咱們自定義instanceof
行爲的東西,以上代碼等同於typeof 'hello world' === 'string'
,因此結果天然是true
了。這其實也側面反映了一個問題,instanceof
也不是百分之百可信的。
function type(e) {
return Object.prototype.toString.call(e).slice(8, -1);
}
console.log(type(null))
console.log(type(1))
console.log(type('zenquan'))
console.log(type(undefined))
console.log(type(Symbol()))
console.log(type(true))
console.log(type(console.log))
複製代碼
Array.isArray()
因此,typeof和instanceof結合起來就能夠數據類型的判斷。