Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
Js的數(shù)據(jù)類型檢測(cè)在實(shí)際開發(fā)項(xiàng)目過程中會(huì)經(jīng)常遇到,這里邊存在很多坑,比如我們初學(xué)Js的時(shí)候可能只知道判斷數(shù)據(jù)類型一個(gè)typeof就萬事大吉了,其實(shí)還有一個(gè),你以為的這兩種就夠用了嗎?就能準(zhǔn)確判斷每種數(shù)據(jù)類型了嗎?不會(huì),還有很多坑等著你去跳,今天我們就把這些坑都刨出來給大家看,一起完美避坑!
1. 通過typeof檢測(cè)
這是我們比較常用的一種類型檢測(cè)方法,通過一段代碼回顧下:
typeof 1 // number
typeof '1' // string
typeof undefined // undefined
typeof true // boolean
typeof Symbol() // symbol
typeof null // object
typeof [] // object
typeof {} // object
typeof console // object
typeof console.log // function
通過以上代碼可以看出,typeof在判斷null之前幾個(gè)基本數(shù)據(jù)類型的時(shí)候基本上是準(zhǔn)確無誤的,可是在判斷null時(shí)返回的是引用類型(object),這明顯是有問題,null壓根就不是引用類型,這是Js本身的一個(gè)bug,還有在判斷數(shù)組類型、對(duì)象以及引用類型上都返回的是object,所以這也是有問題的,只有在判斷類型時(shí)是正確的!
以上這些坑在實(shí)際開發(fā)過程中應(yīng)盡量避免!
2. 通過檢測(cè)
想必 的方法你也聽說過,我們 new 一個(gè)對(duì)象,那么這個(gè)新對(duì)象就是它原型鏈繼承上面的對(duì)象了,通過 我們能判斷這個(gè)對(duì)象是否是之前那個(gè)構(gòu)造函數(shù)生成的對(duì)象,這樣就基本可以判斷出這個(gè)新對(duì)象的數(shù)據(jù)類型。下面通過代碼來了解一下。
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('Mercedes Benz')
car instanceof String // true
let str = 'Covid-19'
str instanceof String // false
那么typeof與之間有什么差異呢?
可以準(zhǔn)確地判斷復(fù)雜引用數(shù)據(jù)類型,但是不能正確判斷基礎(chǔ)數(shù)據(jù)類型;而 typeof 也存在弊端,它雖然可以判斷基礎(chǔ)數(shù)據(jù)類型(null 除外),但是引用數(shù)據(jù)類型中,除了 類型以外,其他的也無法判斷。
總之,不管單獨(dú)用 typeof 還是 ,都不能滿足所有場(chǎng)景的需求,而只能通過二者混寫的方式來判斷。但是,即使采用兩種混寫的方式,也只能檢測(cè)大多數(shù)情況,并且寫起來也相當(dāng)難受!
所以,在實(shí)際開發(fā)中,推薦采用第三種判斷方法!
3. 通過Object..檢測(cè)
() 是 Object 的原型方法,調(diào)用該方法,可以統(tǒng)一返回格式為 “[object Xxx]” 的字符串,其中 Xxx 就是對(duì)象的類型。對(duì)于 Object 對(duì)象,直接調(diào)用 () 就能返回 [object Object];而對(duì)于其他對(duì)象,則需要通過 call 來調(diào)用,才能返回正確的類型信息。我們來看一下代碼。
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上結(jié)果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
從上面這段代碼可以看出,Object...call() 可以很好地判斷引用類型,甚至可以把 和 window 都區(qū)分開來。
但是在寫判斷條件的時(shí)候一定要注意,使用這個(gè)方法最后返回統(tǒng)一字符串格式為 "[object Xxx]" ,而這里字符串里面的 "Xxx" ,第一個(gè)首字母要大寫(注意:使用 typeof 返回的是小寫),這里需要多加留意。
那么下面來實(shí)現(xiàn)一個(gè)全局通用的數(shù)據(jù)類型判斷方法,來加深理解,代碼如下。
function getType(obj){
let type = typeof obj;
if (type !== "object") { // 先進(jìn)行typeof判斷,如果是基礎(chǔ)數(shù)據(jù)類型,直接返回
return type;
}
// 對(duì)于typeof返回結(jié)果是object的,再進(jìn)行如下的判斷,正則返回結(jié)果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); // 注意正則中間有個(gè)空格
}
/* 代碼驗(yàn)證,需要注意大小寫,哪些是typeof判斷,哪些是toString判斷?思考下 */
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大寫,typeof null是object,需toString來判斷
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判斷,因此首字母小寫
getType(/123/g) //"RegExp" toString返回
以上就是Js中檢測(cè)數(shù)據(jù)的三種方法,最后實(shí)現(xiàn)了一個(gè)通用類檢測(cè)方法,基本上可以搞定所有數(shù)據(jù)類型的檢測(cè),每一種方法都有自己的強(qiáng)項(xiàng)和不足,我們?cè)谑褂眠^程中,還是要看業(yè)務(wù)場(chǎng)景具體選擇!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。