厲害了!這是JavaScript中的數(shù)據(jù)類型判斷方法最全總結(jié)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
在 JavaScript 中,主要有七種基本數(shù)據(jù)類型Undefined、Null、Boolean、Number、String、Symbol、BigInt,還有一種復(fù)雜數(shù)據(jù)類型Object,其中包含了Data、function、Array、RegExp等。JavaScript 不支持任何創(chuàng)建自定義類型的機(jī)制,而所有值最終都將是上述8種數(shù)據(jù)類型之一。由于JavaScript 是一種動(dòng)態(tài)類型語(yǔ)言,這意味著你可以在程序執(zhí)行過(guò)程中改變變量的類型。 基本數(shù)據(jù)類型與引用數(shù)據(jù)類型的區(qū)別:基本數(shù)據(jù)類型是指存放在棧(stack)中的簡(jiǎn)單數(shù)據(jù)段,數(shù)據(jù)大小確定,內(nèi)存空間大小可以分配,它們是直接按值存放的,所以可以直接按值訪問(wèn)引用類型是存放在堆(heap)內(nèi)存中的對(duì)象,變量其實(shí)是保存的在棧內(nèi)存中的一個(gè)指針(保存的是堆內(nèi)存中的引用地址),這個(gè)指針指向堆內(nèi)存。引用類型數(shù)據(jù)在棧內(nèi)存中保存的實(shí)際上是對(duì)象在堆內(nèi)存中的引用地址。通過(guò)這個(gè)引用地址可以快速查找到保存中堆內(nèi)存中的對(duì)象。 那么,在實(shí)際工作代碼開(kāi)發(fā)中,有哪些方法去判斷一個(gè)數(shù)據(jù)是哪種數(shù)據(jù)類型呢?這就是本篇文章要重點(diǎn)介紹的內(nèi)容——JavaScript中的數(shù)據(jù)類型判斷方法大全! typeof 運(yùn)算符是 JavaScript 的基礎(chǔ)知識(shí)點(diǎn),盡管它存在一定的局限性(見(jiàn)下文),但在前端js的實(shí)際編碼過(guò)程中,仍然是使用比較多的類型判斷方式。因此,掌握該運(yùn)算符的特點(diǎn),對(duì)于寫(xiě)出好的代碼,就會(huì)起到很大的幫助作用。 typeof 運(yùn)算符可能返回的類型字符串有:string, boolean, number, bigint, symbol, undefined, function, object。
需要注意的是typeof null返回為object,因?yàn)樘厥庵祅ull被認(rèn)為是一個(gè)空的對(duì)象引用。這是 JavaScript 語(yǔ)言的一個(gè)歷史遺留問(wèn)題。在JavaScript 最初的版本中,使用 32 位的值表示一個(gè)變量,其中前 3 位用于表示值的類型。000 表示對(duì)象,010 表示浮點(diǎn)數(shù),100 表示字符串,110 表示布爾值,和其他的值都被認(rèn)為是指針。在這種表示法下,null 被解釋為一個(gè)全零的指針,也就是說(shuō)它被認(rèn)為是一個(gè)空對(duì)象引用,因此 typeof null的結(jié)果就是 "object"。 typeof 的局限性:在于無(wú)法精確判斷出 null、數(shù)組、對(duì)象、正則 的類型。引用類型,除了function返回function類型外,其它均返回object。所以如果要精準(zhǔn)判斷,還需要使用其他技術(shù)手段,或組合判斷(見(jiàn)下文)。 在 JS 的原型鏈和原型對(duì)象中,會(huì)通過(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ù),也就是自己的類型了。
注意:
instanceof 運(yùn)算符用于檢測(cè)構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在某個(gè)實(shí)例對(duì)象的原型鏈上。也就是說(shuō)檢測(cè)實(shí)例對(duì)象是不是屬于某個(gè)構(gòu)造函數(shù),可以用來(lái)做數(shù)據(jù)類型的檢測(cè)。不能檢測(cè)基本數(shù)據(jù)類型,只可用來(lái)判斷引用數(shù)據(jù)。
通過(guò)上面代碼可以看到,instanceof 既能夠判斷出 [ ] 是Array的實(shí)例,又能判斷出 [ ] 也是Object的實(shí)例,這是為什么呢? 通過(guò)《一文讓你搞懂javascript中的構(gòu)造函數(shù)、實(shí)例、原型、原型鏈,和它們之間的關(guān)系》這篇文章就可以明白其原因了。instanceof 能夠判斷出 [ ].__proto__ 指向 Array.prototype,而 Array.prototype.__proto__ 又指向了Object.prototype,最終Object.prototype.__proto__ 指向了null,標(biāo)志著原型鏈的結(jié)束。因此,[ ]、Array、Object 就在內(nèi)部形成了一條原型鏈。 缺點(diǎn):
2. 原型鏈可能被修改,導(dǎo)致檢測(cè)結(jié)果不準(zhǔn)確。 Object.prototype.toString——專業(yè)檢測(cè)數(shù)據(jù)類型一百年! 它是一個(gè)專門(mén)檢測(cè)數(shù)據(jù)類型的方法。 原理:當(dāng)調(diào)用 Object.prototype.toString 時(shí),JavaScript會(huì)將該調(diào)用傳遞給我們需要檢查類型的對(duì)象。因?yàn)镺bject.prototype.toString是一個(gè)函數(shù),所以傳遞給它的唯一參數(shù)是this,而且該參數(shù)是一個(gè)隱式參數(shù)。具體如下:Object.prototype.toString.call(obj),由于toString是Object.prototype上的方法,因此我們傳遞給它的參數(shù)應(yīng)該是一個(gè)對(duì)象,而Object.prototype.toString方法本身卻沒(méi)有傳遞參數(shù)。這就是為什么我們需要用call將它與需要檢查類型的對(duì)象連接起來(lái)。該方法可以指定函數(shù)內(nèi)的this關(guān)鍵字上下文。因此,我們將檢查類型的對(duì)象作為首個(gè)參數(shù)傳遞給了toString方法,并使用call方法將Object.prototype.toString作為一個(gè)函數(shù)來(lái)執(zhí)行。這樣JavaScript就會(huì)在上下文對(duì)象上執(zhí)行Object.prototype.toString方法,從而返回一個(gè)表示該對(duì)象類型的字符串。
編寫(xiě)一個(gè)函數(shù),對(duì)返回的字符串從第8位做一個(gè)截取,截取到倒數(shù)第一位,再去做類型比較。Array.isArray() 檢查傳遞的值是否為Array。它不檢查值的原型鏈,也不依賴于它所附加的 Array 構(gòu)造函數(shù)。對(duì)于使用數(shù)組字面量語(yǔ)法或 Array 構(gòu)造函數(shù)創(chuàng)建的任何值,它都會(huì)返回 true。 Array.isArray() 也拒絕原型鏈中帶有 Array.prototype,而實(shí)際不是數(shù)組的對(duì)象,但 instanceof Array 會(huì)接受。
JS 中有一個(gè)特殊的數(shù)字——NaN,表示 not a number,不是一個(gè)數(shù)字,但它卻歸屬于數(shù)字類型。在上文中我們知道 typeof NaN 返回number。NaN 用于表示不是一個(gè)數(shù)字,它不等于任何值,包括它本身。ES6 提供了 Number.isNaN 方法,它能判斷一個(gè)值是否嚴(yán)格等于NaN。
上面的 Object.prototype.toString 方法,之所以對(duì)不同的數(shù)據(jù)類型,返回不同的標(biāo)識(shí)字符串,就是因?yàn)?nbsp;Symbol.toStringTag 。Symbol.toStringTag 是一個(gè)內(nèi)置符號(hào)屬性,它的值是一個(gè)字符串,用于表示一個(gè)對(duì)象的默認(rèn)描述,也就是調(diào)用 Object.prototype.toString 會(huì)返回的內(nèi)容。
Symbol.toStringTag主要適用于需自定義類型的場(chǎng)景。 對(duì)于自定義對(duì)象,調(diào)用 Object.prototype.toString.call()方法,都只會(huì)返回 [object Object]。此時(shí)就可以使用 Symbol.toStringTag 來(lái)指定一個(gè)確定的類型了。
Object.getPrototypeOf() 靜態(tài)方法返回指定對(duì)象的原型,即內(nèi)部 [[Prototype]] 屬性的值。
isPrototypeOf() 是 Object函數(shù)(類)的下的一個(gè)方法,用于判斷當(dāng)前對(duì)象是否為另外一個(gè)對(duì)象的原型,如果是就返回 true,否則就返回 false。
obj對(duì)象是Object的實(shí)例,所以obj對(duì)象的原型(__proto__)指向Object的原型(prototype),上面會(huì)輸出true。
因?yàn)閔uman對(duì)象是Human的實(shí)例,所以human對(duì)象的原型(__proto__)指向Human的原型(prototype),上面會(huì)輸出true。 JavaScript中內(nèi)置類Number、String、Boolean、Function、Array因?yàn)槎际抢^承Object,所以下面的輸出也都是true。
另外值得一提的是 Function.prototype 也是Object的原型,因?yàn)镺bject也是一個(gè)函數(shù)(類),它們是互相生成的。
與instanceof的區(qū)別:instanceof 作用的原理就是判斷實(shí)例的原型鏈中能否找到類的原型對(duì)象(prototype),而 isPrototypeOf 又是判斷類的原型對(duì)象(prototype)是否在實(shí)例的原型鏈上。這兩個(gè)表達(dá)的意思是一致的,之是寫(xiě)法不同而已。 instanceof的寫(xiě)法:A instanceof B,isPrototypeOf的寫(xiě)法:B.prototype.isPrototypeOf(A)。 直接通過(guò)與一個(gè)特定的值進(jìn)行比較,從而判斷數(shù)據(jù)的類型。主要適用undefined、 window、 document、 null 等。
如何判斷當(dāng)前腳本運(yùn)行在瀏覽器還是node環(huán)境中?
該文章在 2024/4/19 18:05:26 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |