JavaScript 的數據類型檢測是咱們平時開發中常常會遇到的場景,小到基本數據類型大至各類引用數據類型的檢測,都是咱們須要掌握的知識點。本章會詳細講解 JavaScript 中各類不一樣數據類型的檢測方法以及最後會實現一個數據類型檢測的終極方法。前端
紅寶石書告訴咱們,JavaScript 中的數據類型有 Undefined、Null、Boolean、Number、String、Object,其中前五種是基本類型,而 Object 是引用類型。實際上,Object 中還包含了其它更爲具體的引用類型,如 Array、Function、Date、RegExp、Error、Arguments 等。bash
在本章的敘述中,我都會以上述 12 種數據類型爲基礎來講明不一樣的檢測方式(實際上 JavaScript 中數據類型不止 12 種,其它數據類型咱們鮮少碰到,因此在此就很少作贅述啦)。函數
咱們一般用來檢測數據類型的方法,分別是 typeof 和 Object.prototype.toString,讓咱們仔細來看看這兩個方法。學習
MDN 中的敘述是,typeof 操做符返回一個字符串,表示未經計算的操做數的類型。ui
其使用方式是 typeof operand 或 typeof(operand),operand 是一個表達式,表示對象或原始值,其類型將被返回,返回值是表示其數據類型的字符串的小寫形式。spa
那麼讓咱們直接來看一下上述的 12 種數據類型使用 typeof 來檢測後返回值分別是什麼:prototype
var und=undefined;
var nul=null;
var boo=true;
var num=1;
var str='xys'
var obj=new Object();
var arr=[1,2,3];
var fun=function(){}
var date=new Date();
var reg = /a/g;
var err=new Error()
var arg;
(function getArg(){
arg=arguments;
})();
console.log(typeof und); // undefined
console.log(typeof nul); // object
console.log(typeof boo); // boolean
console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof obj); // object
console.log(typeof arr); // object
console.log(typeof fun); // function
console.log(typeof date); // object
console.log(typeof reg); // object
console.log(typeof err); // object
console.log(typeof arg); // object
複製代碼
能夠看到,使用 typeof 方法來檢測數據類型,基本類型大部分都能被準確檢測並返回正確的字符串(除了 Null 類型,其返回 object 字符串),而引用類型大部分都不可以被準確檢測(除了 Function 類型可以準確返回 function 字符串外,其它的都返回了 object 字符串)。code
由此可得,typeof 方法並不可以徹底精準地檢測出上述 JavaScript 中的 12 中數據類型。cdn
ES5 規範中是這麼描述 Object.prototype.toString 的:對象
能夠知道,Object.prototype.toString 最終會返回形式如 [object,class] 的字符串,class 指代的是其檢測出的數據類型,這個是咱們判斷數據類型的關鍵。
一樣的,讓咱們來看下使用 Object.prototype.toString 來檢測上述列舉到的 12 種數據類型都會返回什麼樣的結果:
var toString=Object.prototype.toString;
console.log(toString.call(und)); // [object Undefined]
console.log(toString.call(nul)); // [object Null]
console.log(toString.call(boo)); // [object Boolean]
console.log(toString.call(num)); // [object Number]
console.log(toString.call(str)); // [object String]
console.log(toString.call(obj)); // [object Object]
console.log(toString.call(arr)); // [object Array]
console.log(toString.call(fun)); // [object Function]
console.log(toString.call(date)); // [object Date]
console.log(toString.call(reg)); // [object RegExp]
console.log(toString.call(err)); // [object Error]
console.log(toString.call(arg)); // [object Arguments]
複製代碼
能夠看到,Object.prototype.toString 返回的 [object,class] 字符串中,class 準確的表示了各個數據的類型,與 typeof 不一樣的是,class 所表明的數據類型字符串首字母是大寫的,而不像 typeof 返回的是小寫字符串。
經過上述對兩個檢測數據類型方法的介紹,咱們知道 typeof 可以被用來檢測除 Null 類型外的其它基本類型,而且可以檢測出引用類型中 Function 數據類型,而 Object.prototype.toString 可以檢測出全部的數據類型,因此咱們能夠結合這兩個方法來實現一個 JavaScript 數據類型檢測的終極方法。
/**
* @desc 數據類型檢測
* @param obj 待檢測的數據
* @return {String} 類型字符串
*/
function type(obj) {
return typeof obj !== "object" ? typeof obj : Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
複製代碼
有時咱們但願直接判斷一個數據是不是某個類型,那麼咱們能夠單獨實現這些判斷某個數據類型的函數,這裏直接給出各個函數的實現代碼,須要的童鞋能夠直接使用。
/**
* @desc 是不是 Undefined 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isUndefined(obj) {
return obj === void 0;
}
/**
* @desc 是不是 Null 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isNull(obj) {
return obj === null;
}
/**
* @desc 是不是 Boolean 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isBoolean(obj) {
return typeof(obj) === 'boolean';
}
/**
* @desc 是不是 Number 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isNumber(obj) {
return typeof(obj) === 'number';
}
/**
* @desc 是不是 String 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isString(obj) {
return typeof(obj) === 'string';
}
/**
* @desc 是不是 Object 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/**
* @desc 是不是 Array 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isArray(obj){
return Array.isArray?Array.isArray(obj):Object.prototype.toString.call(obj) === '[object Array]';
}
/**
* @desc 是不是 Function 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isFunction(obj){
return typeof(obj) === 'function';
}
/**
* @desc 是不是 Date 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isDate(obj){
return Object.prototype.toString.call(obj) === '[object Date]';
}
/**
* @desc 是不是 RegExp 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isRegExp(obj){
return Object.prototype.toString.call(obj) === '[object RegExp]';
}
/**
* @desc 是不是 Error 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isError(obj){
return Object.prototype.toString.call(obj) === '[object Error]';
}
/**
* @desc 是不是 Arguments 類型檢測
* @param obj 待檢測的數據
* @return {Boolean} 布爾值
*/
function isArguments(obj){
return Object.prototype.toString.call(obj) === '[object Arguments]';
}
複製代碼
不定時分享我的在前端方面的學習經驗,以爲還不錯的小夥伴,能夠關注一波公衆號哦。