JavaScript 的数据类型检测是咱们平时开发中常常会遇到的场景,小到基本数据类型大至各类引用数据类型的检测,都是咱们须要掌握的知识点。下文会主要讲解 JavaScript 中各类不一样数据类型的检测方法以及最后会实现一个数据类型检测的终极方法。bash
红宝石书告诉咱们,JavaScript 中的数据类型有 Undefined
、Null
、Boolean
、Number
、String
、Object
,其中前五种是基本类型,而 Object
是引用类型。实际上,Object
中还包含了其它更为具体的引用类型,如 Array
、Function
、Date
、RegExp
、Error
、Arguments
等。函数
在本章的叙述中,我都会以上述 12 种数据类型为基础来讲明不一样的检测方式(实际上 JavaScript 中数据类型不止 12 种,其它数据类型咱们鲜少碰到,因此在此就很少作赘述啦)。ui
咱们一般用来检测数据类型的方法,分别是 typeof
和 Object.prototype.toString
,让咱们仔细来看看这两个方法。spa
typeofprototype
MDN 中的叙述是,typeof
操做符返回一个字符串,表示未经计算的操做数的类型。code
其使用方式是 typeof operand
或 typeof(operand)
,operand
是一个表达式,表示对象或原始值,其类型将被返回,返回值是表示其数据类型的字符串的小写形式。cdn
那么让咱们直接来看一下上述的 12 种数据类型使用 typeof
来检测后返回值分别是什么:对象
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
字符串)。blog
由此可得,typeof
方法并不可以彻底精准地检测出上述 JavaScript 中的 12 中数据类型。ip
Object.prototype.toString
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]';
}
复制代码