別再被坑了! JavaScript類(lèi)型檢測(cè)的最佳實(shí)踐

別再被坑了! JavaScript類(lèi)型檢測(cè)的最佳實(shí)踐

在 JavaScript 中,我們經(jīng)常需要判斷一個(gè)變量的類(lèi)型弯淘。這個(gè)需求在編程中非常常見(jiàn),因?yàn)椴煌?lèi)型的數(shù)據(jù)會(huì)影響到我們的代碼邏輯。

JavaScript 提供了幾種方法來(lái)檢測(cè)數(shù)據(jù)類(lèi)型,每種方法都有自己的優(yōu)缺點(diǎn)璃搜。

Object.prototype.toString.call()

這是最萬(wàn)能的方法。它可以準(zhǔn)確識(shí)別所有的 JavaScript 內(nèi)置類(lèi)型,包括基本類(lèi)型和復(fù)雜類(lèi)型鳞上。不管你給它傳什么數(shù)據(jù),它都能給出一個(gè)統(tǒng)一格式的字符串,告訴你這個(gè)數(shù)據(jù)到底是什么類(lèi)型这吻。

它的原理是調(diào)用對(duì)象內(nèi)部的 [[Class]] 屬性。這個(gè)屬性是只讀的,不能被改寫(xiě),所以非掣菀椋可靠唾糯。

優(yōu)點(diǎn):

  • 識(shí)別范圍廣,基本類(lèi)型和復(fù)雜類(lèi)型都能識(shí)別
  • 不會(huì)受到對(duì)象自身的 toString() 方法的影響
  • 返回結(jié)果格式統(tǒng)一,方便解析

缺點(diǎn):

  • 寫(xiě)起來(lái)比較啰嗦
  • 如果是自定義類(lèi)型,只能得到 [object Object],不能進(jìn)一步區(qū)分類(lèi)型
function detectType(data) {
    return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
}

console.log(detectType(123)); // 'number'
console.log(detectType('abc')); // 'string'
console.log(detectType(true)); // 'boolean'
console.log(detectType(null)); // 'null'
console.log(detectType(undefined)); // 'undefined'
console.log(detectType([])); // 'array'
console.log(detectType({})); // 'object'
console.log(detectType(function () {})); // 'function'
console.log(detectType(new Date())); // 'date'
console.log(detectType(new RegExp())); // 'regexp'
console.log(detectType(new Error())); // 'error'

typeof

這個(gè)運(yùn)算符最常用,寫(xiě)起來(lái)簡(jiǎn)單。它可以識(shí)別基本類(lèi)型和函數(shù),但對(duì)復(fù)雜類(lèi)型的識(shí)別能力有限鬼贱。

優(yōu)點(diǎn):

  • 使用簡(jiǎn)單
  • 可以識(shí)別基本類(lèi)型和函數(shù)

缺點(diǎn):

  • 無(wú)法區(qū)分?jǐn)?shù)組和普通對(duì)象
  • typeof null 的結(jié)果是 'object'
  • 無(wú)法識(shí)別內(nèi)置對(duì)象類(lèi)型,如 Date移怯、RegExp
console.log(typeof 123); // 'number'
console.log(typeof 'abc'); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' (這是一個(gè)歷史遺留的 bug)
console.log(typeof []); // 'object'
console.log(typeof {}); // 'object'
console.log(typeof function () {}); // 'function'

instanceof

instanceof 運(yùn)算符用于測(cè)試構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在對(duì)象的原型鏈中的任何位置。

優(yōu)點(diǎn):

  • 可以檢查對(duì)象是否屬于特定的類(lèi)或構(gòu)造函數(shù)

缺點(diǎn):

  • 只能檢查對(duì)象類(lèi)型,不能檢查基本類(lèi)型
  • 要識(shí)別多種類(lèi)型,需要多次調(diào)用
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(function () {} instanceof Function); // true
console.log(new Date() instanceof Date); // true
console.log(new RegExp() instanceof RegExp); // true
console.log(new Error() instanceof Error); // true

console.log(123 instanceof Number); // false
console.log('abc' instanceof String); // false
console.log(true instanceof Boolean); // false

constructor

constructor 是對(duì)象的一個(gè)屬性,指向創(chuàng)建該對(duì)象的構(gòu)造函數(shù)这难≈畚螅可以用它來(lái)判斷對(duì)象的類(lèi)型。

優(yōu)點(diǎn):

  • 可以識(shí)別大多數(shù)對(duì)象類(lèi)型,包括自定義類(lèi)型

缺點(diǎn):

  • 如果對(duì)象的 constructor 屬性被修改,會(huì)得到錯(cuò)誤結(jié)果
  • nullundefined 沒(méi)有 constructor 屬性
console.log((123).constructor === Number); // true
console.log('abc'.constructor === String); // true
console.log(true.constructor === Boolean); // true
console.log([].constructor === Array); // true
console.log({}.constructor === Object); // true
console.log(function () {}.constructor === Function); // true
console.log(new Date().constructor === Date); // true
console.log(new RegExp().constructor === RegExp); // true
console.log(new Error().constructor === Error); // true

總結(jié)

如果需要全面準(zhǔn)確的類(lèi)型識(shí)別,Object.prototype.toString.call() 是最佳選擇雁佳。
如果只需要簡(jiǎn)單區(qū)分基本類(lèi)型,typeof 就足夠了脐帝。
如果要檢查對(duì)象是否屬于特定類(lèi)型,可以用 instanceof

在實(shí)際應(yīng)用中,我們可以根據(jù)具體需求選擇合適的方法糖权。

結(jié)語(yǔ)

上次我開(kāi)發(fā)了一個(gè)工具堵腹,可以批量清理無(wú)用的倉(cāng)庫(kù)。如果你感興趣星澳,可以去看看哦疚顷!??

介紹文章https://mp.weixin.qq.com/s/t7lgc6b7xJiNhfm5vWo5-A

GitHub 倉(cāng)庫(kù)地址https://github.com/yaolife ng0629/del-repos

如果你覺(jué)得這個(gè)工具對(duì)你有所幫助,請(qǐng)不要忘記給我的 GitHub 倉(cāng)庫(kù) 點(diǎn)個(gè) Star ?!你的支持是我前進(jìn)的動(dòng)力腿堤!

感謝閱讀阀坏,我們下次再見(jiàn)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笆檀,一起剝皮案震驚了整個(gè)濱河市忌堂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酗洒,老刑警劉巖士修,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異樱衷,居然都是意外死亡棋嘲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)矩桂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沸移,“玉大人,你說(shuō)我怎么就攤上這事侄榴”⒙啵” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵牲蜀,是天一觀的道長(zhǎng)笆制。 經(jīng)常有香客問(wèn)我绅这,道長(zhǎng)涣达,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任证薇,我火速辦了婚禮度苔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浑度。我一直安慰自己寇窑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布箩张。 她就那樣靜靜地躺著甩骏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪先慷。 梳的紋絲不亂的頭發(fā)上饮笛,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音论熙,去河邊找鬼福青。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的无午。 我是一名探鬼主播媒役,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宪迟!你這毒婦竟也來(lái)了酣衷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤次泽,失蹤者是張志新(化名)和其女友劉穎鸥诽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體箕憾,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牡借,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了袭异。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钠龙。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖御铃,靈堂內(nèi)的尸體忽然破棺而出碴里,到底是詐尸還是另有隱情,我是刑警寧澤上真,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布咬腋,位于F島的核電站,受9級(jí)特大地震影響睡互,放射性物質(zhì)發(fā)生泄漏根竿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一就珠、第九天 我趴在偏房一處隱蔽的房頂上張望寇壳。 院中可真熱鬧,春花似錦妻怎、人聲如沸壳炎。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匿辩。三九已至,卻和暖如春榛丢,著一層夾襖步出監(jiān)牢的瞬間铲球,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工涕滋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留睬辐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像溯饵,于是被迫代替她去往敵國(guó)和親侵俗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容