相信一提到怎麼判斷js的資料型別,大家都會想到的是typeof、instanceof,那麼為什麼有了typeof的存在還要有instanceof?
typeof?
根據MDN:typeof操作符返回一個字串,表示未經計算的運算元的型別。
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’
這樣也不能知道是Number還是Boolean還是String
typeof Number // "function"
typeof Boolean // "function"
typeof String // "function"
複製程式碼
instanceof?
因為typeof有了以上的問題,所以才有了instanceof。
根據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([])
複製程式碼
結合typeof和instanceof實現判斷是否為原始型別
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
也不是百分之百可信的。
判斷資料型別的方法
- Object.prototype.toString.call(e).slice(8, -1)
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))
複製程式碼
- type: JS型別檢測庫,彌補typeof的問題,原生相容IE6
- 通過一些系統自帶的API函式來判斷,eg:
Array.isArray()
所以,typeof和instanceof結合起來就可以資料型別的判斷。