1. 程式人生 > >js一行程式碼獲取精確資料型別

js一行程式碼獲取精確資料型別

typeof 是用來獲取一個JavaScript資料型別的操作符,但是有經驗的開發者都知道typeof在某些情況下是無法返回資料精確型別的,比如

document.write(typeof []);

返回的並不是 array ,而是object,所以是無法通過typeof分辨 [] 和 {} 的型別的,那麼有解決方案嗎?先上程式碼

var toType=function (obj){
    return Object.prototype.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}

接下來,來解釋一下上面的程式碼

toString

toString()是核心,該方法返回 [object type] 其中type 就是物件的型別

但是預設情況下,toString()方法會被每個Object重寫,比如陣列的toString就被重寫成了

document.write([1,2,3].toString());  //1,2,3

所以為什麼要用Object 原型上的toString()?就是為了避免使用到被重寫的toString()方法,當然你也可以用一個新的自定義的物件,他的toString()方法是沒有被重寫的

document.write(({}).toString());  //[object Object]

注意,由於{}的特殊性,這裡的{}必須加上小括號,

Object.prototype.toString.call(obj)  作用在各種資料型別的結果如下:

Object.prototype.toString.call(null)
"[object Null]"
Object.prototype.toString.call(undefined)
"[object Undefined]"
Object.prototype.toString.call('hello')
"[object String]"
Object.prototype.toString.call({})
"[object Object]"
Object.prototype.toString.call([])
"[object Array]"
Object.prototype.toString.call(10)
"[object Number]"
Object.prototype.toString.call(true)
"[object Boolean]"
Object.prototype.toString.call(function(){})
"[object Function]"
Object.prototype.toString.call(new Date())
"[object Date]"
Object.prototype.toString.call(/\s/)
"[object RegExp]"

可以發現我們想要的資料精確型別結果都可以通過 toString 來獲得。

提取

拿到toString()的結果後,就該提取具體的型別值了,比如陣列的 [object Array] 方法有很多,對於諸如此類的字串提取,正則表示式絕對是一個好選擇,這裡我們用到了字串的 match 方法

"[object Array]".match(/\s([a-zA-Z]+)/)

實際上就是匹配以空格開始(\s)的字串,注意這裡的括號,這回作為match方法返回陣列中的一項,可以直接拿到不帶空格的結果值,如果不加括號就會發現只有一個帶空格的Array,完事還得處理,最後就是拿到索引為1的結果,有需要再用到toLowerCase()轉為小寫

總結

toString()方法是獲取資料精確型別的核心,可以用

Object.prototype.toString.call(obj)

也可以用

({}).toString.call(obj)