js中如何準確的判斷一個變量的類型?

這是一個高頻面試題,咱們開發中也進程會遇到,今天咱們來實現一個函數getValType(val),用來獲取一個變量的類型。從1. JS基礎變量類型。2. Js中判斷變量的函數。 3. 實現getValType函數。3個方面來分析實現。javascript

Js基礎變量類型

JS 中,有 5 種基本數據類型和 1 種複雜數據類型,基本數據類型有:Undefined, Null, Boolean, NumberString;複雜數據類型是ObjectObject中還細分了不少具體的類型,好比:Array, Function, Date等等。前端

判斷變量的函數

咱們先定義一組變量來用下面的函數來測試:java

var allVarMap = {
    // 數字
    num:123,
    // Infinity
    num1: 1 / 0,
    // NaN
    num2: null / 0,
    // 字符串
    str: 'abcdef',
    // 布爾類型
    bool: true,
    // 數組
    arr :[1, 2, 3, 4],
    // json對象
    json :{name:'wenzi', age:25},
    // 函數
    func:function(){ console.log('this is function'); },
    // 箭頭函數
    func1: () => {console.log('arrow function')},
    // undefined類型
    und:undefined,
    // null類型
    nul:null,
    // date類型
    date:new Date(),
    // 正則表達式
    reg :/^[a-zA-Z]{5,20}$/,
    // 異常類型
    error:new Error()
}
typeof判斷變量類型
typeof運算符用於判斷對象的類型,可是對於一些建立的對象,它們都會返回 object。咱們用該函數來判斷上面的結果:
var results = []
for (let i in allVarMap) {
    results.push(typeof allVarMap[i])
}
console.log(results.join())
// number,number,number,string,boolean,object,object,function,function,undefined,object,object,object,object

能夠看到,NaNInfinity都檢查爲number類型,其餘的 string,function,boolean,undefined包括箭頭函數都能正確檢查出來,可是對於reg,date,null都獲得了object。看來還須要具體的判斷。面試

instanceof檢查
ECMAScript 引入了另外一個 Java 運算符 instanceof 來解決這個問題。 instanceof 運算符與 typeof 運算符類似,用於識別正在處理的對象的類型。 instanceof運算符用來判斷一個構造函數的 prototype屬性所指向的對象是否存在另一個要檢測對象的原型鏈上。與 typeof 方法不一樣的是, instanceof 方法要求開發者明確地確認對象爲某特定類型。
console.log(allVarMap.date instanceof Date) // true
console.log(allVarMap.func instanceof Function) // true

能夠看到instanceof能夠正確判斷出date,func的類型,可是前提是已知該變量的類型,因此這裏不符合咱們的預期。正則表達式

使用Object.prototype.toString.call
定義:首先,取得對象的一個內部屬性[[Class]],而後依據這個屬性,返回一個相似於」[object Array]「的字符串做爲結果(看過ECMA標準的應該都知道,[[]]用來表示語言內部用到的、外部不可直接訪問的屬性,稱爲「內部屬性」)。利用這個方法,再配合call,咱們能夠取得任何對象的內部屬性[[Class]],而後把類型檢測轉化爲字符串比較,以達到咱們的目的。
咱們看看下面的函數運行結果:
var results = []
for (let i in allVarMap) {
    results.push(Object.prototype.toString.call(allVarMap[i]))
}
console.log(results.join())
// [object Number],[object Number],[object Number],[object String],[object Boolean],[object Array],[object Object],[object Function],[object Function],[object Undefined],[object Null],[object Date],[object RegExp],[object Error]

能夠看到該函數正確的返回了全部變量的類型,咱們只要取出返回結果中的字符串,就能獲得變量的類型。json

實現getValType函數

根據上面的分析,咱們能夠先用typeOf函數判斷出基礎類型number,string,function,boolean,undefined。而後若是結果是object,咱們再用Object.prototype.toString.call來判斷出具體的類型。數組

var getVarType = function (val = 0) {
    var type = typeof val
    // object須要使用Object.prototype.toString.call判斷
    if (type === 'object') {
        var typeStr = Object.prototype.toString.call(val)
        // 解析[object String]
        typeStr = typeStr.split(' ')[1]
        type = typeStr.substring(0, typeStr.length - 1)
    }
    return type
}
var results = []
for (let i in allVarMap) {
    results.push(getVarType(allVarMap[i]))
}
console.log(results.join())
// number,number,number,string,boolean,Array,Object,function,function,number,Null,Date,RegExp,Error

能夠看到,完美判斷出了全部變量的類型,該函數能夠再添加一些邏輯,判斷一個變量是不是NaN,Infinity之類的特殊需求。函數

總結

  1. typeOf能判斷出一個變量的類型,可是隻能判斷出number,string,function,boolean,undefined,null和其餘對象類型返回結果都爲object.
  2. instanceof能判斷出一個對象是不是另外一個類的實例。
  3. Object.prototype.toString.call能判斷出全部變量的類型,返回值爲[Object ***]
學習如逆水行舟,不進則退,前端技術飛速發展,若是天天不堅持學習,就會跟不上,我會陪着你們,天天堅持推送博文,跟你們一同進步,但願你們能關注我,第一時間收到最新文章。

我的公衆號:長按保存關注學習

相關文章
相關標籤/搜索