JavaScript中判斷數(shù)據(jù)類型的實(shí)用方法總結(jié)
前言
最近項(xiàng)目中有不少地方需要判斷數(shù)據(jù)類型,但是判斷數(shù)據(jù)類型也有好幾種方法,并且每種方法判斷的數(shù)據(jù)類型也有局限性,所以想總結(jié)一下,方便以后查閱。
分別是 typeof ,instanceof,Object.prototype.toString.call()
1. typeof
- typeof 它返回值是一個(gè)字符串,該字符串說(shuō)明運(yùn)算數(shù)的類型。返回結(jié)果只有以下幾種:
number,string,boolean,undfined,object,function
- typeof 是用于判斷基本數(shù)據(jù)類型的,除了
null
都可以調(diào)用typeof
顯示正確的類型。 - 但對(duì)于引用數(shù)據(jù)類型,除了函數(shù)之外,都會(huì)顯示
object
,函數(shù)顯示function
; - 需要注意的是,
typeof null
,結(jié)果是“object”
。 這是個(gè)歷史設(shè)計(jì)缺陷。 - 可以使用typeof判斷變量是否存在(比如 if(typeof a!="undfined"){ xxx }),而不要去使用if(a),因?yàn)閍不存在(未聲明)會(huì)報(bào)錯(cuò)。
1. 對(duì)于數(shù)字類型的操作數(shù)而言, typeof 返回的值是 number。比如:typeof(1),返回的值就是number。
2. 對(duì)于字符串類型, typeof 返回的值是 string。比如:typeof("123"),返回的值是string。
3. 對(duì)于布爾類型, typeof 返回的值是 boolean 。比如:typeof(true),返回的值是boolean。
4. 對(duì)于對(duì)象、數(shù)組、null 返回的值是 object 。比如:typeof(window),typeof(document),typeof(null)返回的值都是object。
5. 對(duì)于函數(shù)類型,返回的值是 function。比如:typeof(eval),typeof(Date)返回的值都是function。
6. 如果運(yùn)算數(shù)是沒(méi)有定義的(比如說(shuō)不存在的變量、函數(shù)或者undefined),將返回undefined。 比如:typeof(sss)、typeof(undefined)都返回undefined。
下面 我們將用程序代碼驗(yàn)證一下:
console.log(typeof(1)); //number console.log(typeof(NaN)); //number console.log(typeof("123")); //string console.log(typeof("123" + 12)); //string console.log(typeof("123" + Date)); //string console.log(typeof(true)); //boolean console.log(typeof(window)); //object console.log(typeof(document)); //object console.log(typeof(null)); //object console.log(typeof([8])); //object console.log(typeof({a:1})); //object console.log(typeof(Date)); //function console.log(typeof(sss)); //undefined console.log(typeof(undefined)); //undefined
局限性: 由上面程序代碼可驗(yàn)證,很遺憾的一點(diǎn)是,typeof 在判斷一個(gè) object的數(shù)據(jù)的時(shí)候只能告訴我們這個(gè)數(shù)據(jù)是 object, 而不能細(xì)致的具體到是哪一種 object。所以要 想?yún)^(qū)分對(duì)象、數(shù)組、null,單純使用 typeof 是不行的。
2. instanceof運(yùn)算符
instanceof 運(yùn)算符返回一個(gè)布爾值,表示 對(duì)象是否為某個(gè)構(gòu)造函數(shù)的實(shí)例。 注意,instanceof運(yùn)算符最好用于對(duì)象引用類型,不適用原始類型的值。
基本用法:
// 判斷 p 是否為 Person 的實(shí)例 function Person(name) { this.name = name } const p = new Person('sunshine') p instanceof Person // true // 這里的 p 是 Person 函數(shù)構(gòu)造出來(lái)的,所以順著 p 的原型鏈可以找到 Object 的構(gòu)造函數(shù) p.__proto__ === Person.prototype // true p.__proto__.__proto__ === Object.prototype // true
缺點(diǎn):
對(duì)于基本類型的數(shù)據(jù),instanceof是不能直接判斷它的類型的,因?yàn)閷?shí)例是一個(gè)對(duì)象或函數(shù)創(chuàng)建的,是引用類型,所以需要通過(guò)基本類型對(duì)應(yīng)的 包裝對(duì)象 來(lái)判斷。所以對(duì)于 null
和 undefined
這兩個(gè)家伙就檢測(cè)不了了~
5 instanceof Number // false new Number(5) instanceof Number // true
因?yàn)樵玩溊^承的關(guān)系,instanceof 會(huì)把數(shù)組都識(shí)別為 Object 對(duì)象,所有引用類型的祖先都是 Object 對(duì)象
let arr = [1,2,3] console.log(Object.prototype.toString.call(arr) === '[object Array]') // true console.log(arr instanceof Array) // true console.log(arr instanceof Object) // true let fn = function(){} console.log(fn instanceof Object) // true
另外,instanceof 也是能判斷基本數(shù)據(jù)類型的,比如下面這種方式,這個(gè)了解就行,真的要判斷基本數(shù)據(jù)類型還是用 typeof
class PrimitiveNumber { static [Symbol.hasInstance](x) { return typeof x === 'number' } } console.log(111 instanceof PrimitiveNumber) // true
如果你不知道Symbol,可以看看 MDN上關(guān)于hasInstance的解釋
其實(shí)就是自定義instanceof行為的一種方式,這里將原有的instanceof方法重定義,換成了typeof,因此能夠判斷基本數(shù)據(jù)類型。
特殊情況補(bǔ)充:
- instanceof的原理是 檢查
右邊
構(gòu)造函數(shù)的prototype
屬性,是否在左邊
對(duì)象的原型鏈
上;只要處于原型鏈中,判斷永遠(yuǎn)為true。 - 有一種特殊情況,就是左邊對(duì)象的原型鏈上,只有
null
對(duì)象。這時(shí),instanceof判斷會(huì)失真;因?yàn)镺bject不在null原型鏈上
var obj = Object.create(null); typeof obj // "object" obj instanceof Object // false
上面代碼中,Object.create(null) 返回一個(gè)新對(duì)象obj,它的原型是null。右邊構(gòu)造函數(shù)的Object.prototype屬性,不在左邊的原型鏈上,因此instanceof就認(rèn)為obj不是Object的實(shí)例。這是唯一的instanceof運(yùn)算符判斷會(huì)失真的情況(一個(gè)對(duì)象的原型是null)。
下面介紹一種方法,對(duì)每一種數(shù)據(jù)類型都實(shí)用的。
3. Object.prototype.toString.call()
在判斷數(shù)據(jù)類型時(shí),我們稱 Object.prototype.toString 為 “萬(wàn)能方法” “終極方法”,工作中也是比較常用而且準(zhǔn)確。 對(duì)于Object.prototype.toString() 方法,會(huì)返回一個(gè)形如 "[object XXX]" 的字符串
1) 判斷基本類型
Object.prototype.toString.call('stjd') //"[object String]" Object.prototype.toString.call(1) //"[object Number]" Object.prototype.toString.call(true) //"[object Boolean]" Object.prototype.toString.call(null) //"[object Null]" Object.prototype.toString.call(undefined) //"[object Undefined]"
2) 判斷原生引用類型
a 函數(shù)類型
Object.prototype.toString.call(function(){}) //這個(gè)方法就建立在js任何類型皆可視為對(duì)象** // "[object Function]"
b 日期類型
var date = new Date(); Object.prototype.toString.call(date); //”[object Date]”
c 數(shù)組類型
Object.prototype.toString.call([2]) //"[object Array]"
d 對(duì)象類型
Object.prototype.toString.call({q:8}) //"[object Object]"
e 正則表達(dá)式
var reg = /[hbc]at/gi; Object.prototype.toString.call(reg); // "[object RegExp]"
f 自定義類型
function Person(name, age) { this.name = name; this.age = age; } var person = new Person("Rose", 18); Object.prototype.toString.call(person); //”[object Object]”
顯然這種方法不能準(zhǔn)確判斷person是Person類的實(shí)例,而只能用instanceof 操作符來(lái)進(jìn)行判斷,如下所示:
console.log(person instanceof Person);//輸出結(jié)果為true
注意: Object.prototype.toString()本身是允許被修改的,而我們目前所討論的關(guān)于Object.prototype.toString()這個(gè)方法的應(yīng)用都是假設(shè)toString()方法未被修改為前提的。
因?yàn)閷?shí)例對(duì)象有可能會(huì)自定義toString()方法,會(huì)覆蓋Object.prototype.toString(), 所以在使用時(shí),最好加上call()。
有的時(shí)候我們也可以封裝判斷數(shù)據(jù)類型的方法。
// 判斷數(shù)據(jù)類型的函數(shù) function getType(data) { return Object.prototype.toString.call(data).slice(8, -1); } // 使用 if(this.getType(json) == 'Object'){ console.log('Object類型') }else if (this.getType(json) == 'Array'){ console.log('Array類型') }
4. 補(bǔ)充 Array.isArray() 方法
js中的isArray()是Array類型的一個(gè)靜態(tài)方法,使用它可以判斷一個(gè)值是否為數(shù)組。 返回一個(gè)布爾值。
var arr = [1,2,3] console.log(Array.isArray(arr)) //true
該方法可直接返回布爾值,在條件表達(dá)式中,使用該方法非常實(shí)用。
5. 總結(jié)
js數(shù)據(jù)類型的判斷主要有三種方法: typeof ,instanceof,Object.prototype.toString.call()
typeof可以區(qū)分 原始類型,undfined和 function 數(shù)據(jù)類型;
instanceof運(yùn)算符適合判斷對(duì)象數(shù)據(jù)類型,不適用原始類型的值。instanceof的原理是基于原型鏈的查詢,只要處于原型鏈中,判斷永遠(yuǎn)為true;
區(qū)分自定義對(duì)象類型使用 instanceof 操作符;
null instanceof Object,返回false,因?yàn)镺bject不在null原型鏈上;
Object.prototype.toString.call() 區(qū)分的數(shù)據(jù)類型適用范圍更大,但是無(wú)法區(qū)分自定義對(duì)象類型;
判斷數(shù)據(jù)類型方法有很多,實(shí)際使用需要根據(jù)自己的需求使用最適合自己的方法;
到此這篇關(guān)于JavaScript中判斷數(shù)據(jù)類型的實(shí)用方法總結(jié)的文章就介紹到這了,更多相關(guān)JavaScript判斷數(shù)據(jù)類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生JS和jQuery操作DOM對(duì)比總結(jié)
這篇文章主要給大家介紹了原生JS和jQuery操作DOM的一些對(duì)比總結(jié),文中總結(jié)了很多的對(duì)比,相信對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01JavaScript實(shí)現(xiàn)京東購(gòu)物放大鏡和選項(xiàng)卡效果的方法分析
這篇文章主要介紹了JavaScript實(shí)現(xiàn)京東購(gòu)物放大鏡和選項(xiàng)卡效果的方法,結(jié)合實(shí)例形式分析了javascript基于事件響應(yīng)、數(shù)值計(jì)算與頁(yè)面元素動(dòng)態(tài)修改實(shí)現(xiàn)圖片放大功能以及tab選項(xiàng)卡切換效果相關(guān)操作技巧,需要的朋友可以參考下2018-07-07點(diǎn)擊按鈕或鏈接不跳轉(zhuǎn)只刷新頁(yè)面的腳本整理
點(diǎn)擊按鈕或鏈接時(shí)不跳轉(zhuǎn)只刷新頁(yè)面,在某些情況下還是比較實(shí)用的,下面整理些不錯(cuò)的示例,感興趣的朋友可以參考下2013-10-10js實(shí)現(xiàn)點(diǎn)擊每個(gè)li節(jié)點(diǎn),都彈出其文本值及修改
本篇文章主要分享了js實(shí)現(xiàn)點(diǎn)擊每個(gè)li節(jié)點(diǎn),都彈出其文本值及修改的實(shí)例代碼,具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧2016-12-12JS 兩個(gè)字符串時(shí)間的天數(shù)差計(jì)算
本文為大家介紹下兩個(gè)字符串時(shí)間的天數(shù)差的計(jì)算公式,感興趣的朋友可以參考下2013-08-08javascript封裝簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了javascript封裝簡(jiǎn)單實(shí)現(xiàn)方法,涉及javascript中方法與屬性的相關(guān)設(shè)置與使用技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08十個(gè)開(kāi)發(fā)人員面臨的最常見(jiàn)的JavaScript問(wèn)題總結(jié)
今天,JavaScript?是幾乎所有現(xiàn)代?Web?應(yīng)用的核心。這就是為什么JavaScript問(wèn)題,以及找到導(dǎo)致這些問(wèn)題的錯(cuò)誤,是?Web?發(fā)者的首要任務(wù)。本文總結(jié)了十個(gè)常見(jiàn)的問(wèn)題及解決方法,需要的可以參考一下2022-11-11JavaScript實(shí)現(xiàn)多個(gè)重疊層點(diǎn)擊切換效果的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)多個(gè)重疊層點(diǎn)擊切換效果的方法,實(shí)例分析了javascript實(shí)現(xiàn)點(diǎn)擊切換效果的相關(guān)技巧,需要的朋友可以參考下2015-04-04