JS數(shù)據(jù)類型判斷的9種方式總結(jié)
前言
JS 的數(shù)據(jù)類型檢測(cè)是一道經(jīng)典的八股文面試題。相信大家都能條件反射的回答出 4 種方法:typeof、constructor、instanceof 和 Object.prototype.toString,并且對(duì)它們各自的優(yōu)缺點(diǎn)也是張口就來(lái)。
本文對(duì)這些方法做了簡(jiǎn)單歸納,同時(shí)又補(bǔ)充了其他 5 種和數(shù)據(jù)類型檢測(cè)有關(guān)的方法,供諸君食用。
typeof:檢測(cè)基礎(chǔ)數(shù)據(jù)類型和函數(shù)很好用
typeof 應(yīng)該是我學(xué)習(xí)到的第一個(gè) JS 的方法,也是使用頻率最高的一個(gè)用來(lái)檢測(cè)數(shù)據(jù)類型的方法。
它能準(zhǔn)確判斷出的數(shù)據(jù)類型有:Number,String,Boolean,Undefined,Symbol,BigInt,F(xiàn)unction。
它的缺點(diǎn)就是不能準(zhǔn)確判斷 null 的類型,而是返回 “object”。對(duì)于數(shù)組,日期,普通對(duì)象等數(shù)據(jù),統(tǒng)一返回 “object”。
所以在判斷基本數(shù)據(jù)類型(除了 null)和函數(shù)類型時(shí),都會(huì)使用它。
constructor:返回實(shí)例對(duì)象的構(gòu)造函數(shù)
學(xué)習(xí) JS 到面向?qū)ο蟮碾A段時(shí),會(huì)學(xué)到 JS 的原型鏈和原型對(duì)象,會(huì)學(xué)到通過(guò) new 一個(gè)構(gòu)造函數(shù),來(lái)創(chuàng)建實(shí)例對(duì)象。
構(gòu)造函數(shù)的原型對(duì)象上會(huì)有一個(gè) constructor 屬性,指向了構(gòu)造函數(shù)自身,所以實(shí)例對(duì)象通過(guò)原型鏈訪問(wèn) constructor 屬性,就能找到自己的構(gòu)造函數(shù),也就是自己的類型了。
它的本意是用來(lái)標(biāo)識(shí)自己的構(gòu)造函數(shù),卻臨時(shí)拉來(lái)當(dāng)壯丁,用來(lái)判斷數(shù)據(jù)類型,當(dāng)然也存在一定的風(fēng)險(xiǎn):
- null,undefined 沒(méi)有構(gòu)造函數(shù),自然也就訪問(wèn)不到該屬性,因此不能使用此屬性來(lái)判斷
- constructor 可以被改寫,所以不一定準(zhǔn)確
來(lái)看幾個(gè)例子:
console.log((1).constructor === Number) // true ? console.log([1, 2, 3].constructor === Array) // true ? console.log(undefined.constructor === Array) // 報(bào)錯(cuò)
在平時(shí)寫代碼時(shí),基本上不會(huì)用它來(lái)做數(shù)據(jù)類型的檢測(cè)。
instanceof:沿著原型鏈去找
它和 constructor 一樣,也是臨時(shí)拉來(lái)當(dāng)壯丁。它的作用是檢測(cè)實(shí)例對(duì)象是不是屬于某個(gè)構(gòu)造函數(shù),可以用來(lái)做數(shù)據(jù)類型的檢測(cè)。
術(shù)業(yè)有專攻,所以它也有缺點(diǎn):
- 不能檢測(cè)基本數(shù)據(jù)類型
- 原型鏈可能被修改,導(dǎo)致檢測(cè)結(jié)果不準(zhǔn)確
- 只要能在原型鏈上找到構(gòu)造函數(shù),就返回 true,所以類型可能不準(zhǔn)確
來(lái)看幾個(gè)例子:
console.log(1 instanceof Number) // false ? console.log([] instanceof Array) // true ? console.log([] instanceof Object) // true
實(shí)際中 instanceof 也很少用。
Object.prototype.toString:是個(gè)大拿
看名字它是用來(lái)將一個(gè)值轉(zhuǎn)為字符串的,但其實(shí)并不是,它是一個(gè)專門檢測(cè)數(shù)據(jù)類型的方法。
它返回的值是一個(gè)形如 [object Object]
的字符串,比如:
console.log(toString.call('123')) // [object String] console.log(toString.call(null)) // [object Null] console.log(toString.call(true)) // [object Boolean] console.log(toString.call({})) // [object Object] console.log(toString.call([])) // [object Array] console.log(toString.call(function(){})) // [object Function] console.log(toString.call(new Map)) // [object Map] console.log(toString.call(new WeakSet)) // [object WeakSet]
通常會(huì)編寫一個(gè)函數(shù),對(duì)返回的字符串從第8位做一個(gè)截取,截取到倒數(shù)第一位,再去做類型比較。
Symbol.toStringTag:自定義類型
上面的 Object.prototype.toString 方法,之所以對(duì)不同的數(shù)據(jù)類型,返回不同的標(biāo)識(shí)字符串,就是因?yàn)?Symbol.toStringTag
。
Symbol.toStringTag
是一個(gè)內(nèi)置符號(hào)屬性,它的值是一個(gè)字符串,用于表示一個(gè)對(duì)象的默認(rèn)描述,也就是調(diào)用 Object.prototype.toString 會(huì)返回的內(nèi)容,比如:
let obj = {} obj[Symbol.toStringTag] = 'ABC' console.log(Object.prototype.toString.call(obj)) // [object ABC]
對(duì)于自定義對(duì)象,調(diào)用上面的方法,都只會(huì)返回 [object Object]
。此時(shí)就可以使用 Symbol.toStringTag
來(lái)指定一個(gè)確定的類型了,比如:
class Person{ get[Symbol.toStringTag](){ return 'Person' } } let person = new Person() ? console.log(Object.prototype.toString.call(person)) // [object Person]
Object.prototype.isPrototypeOf:和 instanceof 類似
isPrototypeOf 和 instanceof 類似,都是基于原型鏈和原型對(duì)象去做判斷的。它用來(lái)檢查一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈上。
function Person() { } ? let person = new Person() ? console.log(Person.prototype.isPrototypeOf(person))
Array.isArray:專業(yè)檢測(cè)數(shù)組三十年
起初以為它是 ES6 提供的新方法,后來(lái)得知其實(shí)屬于 ES 5.1 規(guī)范。
看名字就知道,它是專門用于檢測(cè)數(shù)組類型的,該方法的命名真實(shí)言簡(jiǎn)意賅。
Array.isArray([]) // true
Number.isNaN
這個(gè)方法就是真的屬于 ES6 標(biāo)準(zhǔn)了。
我們知道,JS 中有一個(gè)特殊的“數(shù)字” NaN,表示 not a number,不是一個(gè)數(shù)字,但它卻歸屬于數(shù)字類型:
console.log(typeof NaN) // 'number'
NaN 用于表示不是一個(gè)數(shù)字,它不等于任何值,包括它本身。在 ES6 之前,windows 對(duì)象提供了一個(gè)全局方法 isNaN
,用于判斷一個(gè)數(shù)字是不是 NaN:
isNaN(10) // false isNaN('abc') // true isNaN(NaN) // true
可以發(fā)現(xiàn),isNaN 對(duì)于字符串的檢測(cè)結(jié)果也是 NaN。但這其實(shí)并不嚴(yán)謹(jǐn),它對(duì)要判斷的數(shù)據(jù)做了一個(gè)隱式類型轉(zhuǎn)換,先轉(zhuǎn)為數(shù)字再進(jìn)行判斷。而NaN 的檢測(cè)應(yīng)該僅限于數(shù)字類型,所以 ES6 提供了 Number.isNaN 方法:
Number.isNaN(NaN) // true Number.isNaN('123') // false
它能判斷一個(gè)值是否嚴(yán)格等于NaN。
等比較:與固定值進(jìn)行比較
直接通過(guò)與一個(gè)特定的值進(jìn)行比較,從而判斷數(shù)據(jù)的類型,比如:
let value = null console.log(value === null) // true ? // 同時(shí)判斷一個(gè)值是 undefined 或者 null let value console.log(value == null) // true
總結(jié)
本文整理了 JS 中常用的判斷數(shù)據(jù)類型的方法,其中 typeof 和 Object.prototype.toString 使用場(chǎng)景是最多的,對(duì)一些特殊的數(shù)據(jù)類型,比如 null,NaN,自定義類型,可以選擇其他的方式去進(jìn)行判斷,做到靈活運(yùn)用。
到此這篇關(guān)于JS數(shù)據(jù)類型判斷的9種方式的文章就介紹到這了,更多相關(guān)JS數(shù)據(jù)類型判斷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中判斷對(duì)象是否為空的方法小結(jié)
在JavaScript中,判斷一個(gè)對(duì)象是否為空可以有多種方法,這篇文章主要為大家詳細(xì)介紹了幾種常見(jiàn)的方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03JS中將多個(gè)逗號(hào)替換為一個(gè)逗號(hào)的實(shí)現(xiàn)代碼
這篇文章主要介紹了JS中將多個(gè)逗號(hào)替換為一個(gè)逗號(hào)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-06-06echarts同一頁(yè)面中四個(gè)圖表切換的js數(shù)據(jù)交互方法示例
這篇文章主要給大家介紹了關(guān)于echarts同一頁(yè)面中四個(gè)圖表切換的js數(shù)據(jù)交互的相關(guān)資料,文中給出了完整的示例代碼供大家參考學(xué)習(xí),對(duì)大家的學(xué)習(xí)或者工作具有一定的幫助,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07寫出更好的JavaScript程序之undefined篇(中)
前一篇我介紹了幾種廣為使用的利用undefined這個(gè)概念值的辦法,這一篇我會(huì)介紹一些不太常見(jiàn)的辦法,其中還包括一個(gè)很巧妙的,我個(gè)人覺(jué)得很值得推廣的辦法。2009-11-11利用NodeJS和PhantomJS抓取網(wǎng)站頁(yè)面信息以及網(wǎng)站截圖
這篇文章主要介紹了利用NodeJS和PhantomJS抓取網(wǎng)站頁(yè)面信息以及網(wǎng)站截圖的方法,提供實(shí)例代碼供大家參考2013-11-11IE6/7/8中Option元素未設(shè)value時(shí)Select將獲取空字符串
可以看到當(dāng)忘記寫option的value時(shí)這些現(xiàn)代瀏覽器都會(huì)盡量返回正確的(客戶端程序員想要的)結(jié)果value,其容錯(cuò)性比IE6/7/8做的更好。2011-04-04JavaScript實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05微信小程序?qū)崿F(xiàn)點(diǎn)擊卡片 翻轉(zhuǎn)效果
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)點(diǎn)擊卡片 翻轉(zhuǎn)效果本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09