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