我所知道的JavaScript中判斷資料型別

Zenquan發表於2019-02-20

相信一提到怎麼判斷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 也不是百分之百可信的。

判斷資料型別的方法

  1. 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))
複製程式碼
  1. type: JS型別檢測庫,彌補typeof的問題,原生相容IE6
  2. 通過一些系統自帶的API函式來判斷,eg: Array.isArray()

所以,typeof和instanceof結合起來就可以資料型別的判斷。

相關文章