在JS中,数据类型可分为基本类型和引用类型,基本数据类型主要有undefined,null,boolean,string,number,Symbol(ES6新增),BigInt(ES10新增)引用类型主要包括Object 、Array 、Date 、RegExp 、Function 等。
# 一、 typeof
typeof是最常用的也是最基本数据类型检测的方法,使用typeof检测数据类型,返回值是字符串格式。能够返回的数据类型有:“number”,“string”,“boolean”,“undefined”,“function”,“object”。
console.log(typeof ""); // string
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof null); // null比较特殊,返回的也是object
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function(){}); // function
不足之处:
- 对于基本类型,除 null 以外,均可以返回正确的结果。
- 对于引用类型,除 function 以外,一律返回 object 类型。
- 对于 null ,返回 object 类型。
- 对于 function 返回 function 类型。
# 二、 instanceof
instanceof用来检测某一个实例是否属于某个类,instanceof主要用来弥补typeof不能检测具体属于哪个对象的局限性。 在这里需要特别注意的是:instanceof 检测的是原型
console.log("1" instanceof String); // false
console.log(1 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log({} instanceof Object); // true
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
特殊情况
null 跟 undefined 直接输出会报错
//以下俩个均报错
// console.log(null instanceof Null);
//console.log(undefined instanceof Undefined);
局限性
instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
# 三、 constructor
console.log(("1").constructor === String);//true
console.log((1).constructor === Number);//true
console.log((true).constructor === Boolean);//true
//console.log((null).constructor === Null); //报错
// console.log((undefined).constructor === Undefined); //报错
console.log(([]).constructor === Array);//true
console.log((function () { }).constructor === Function);//true
console.log(({}).constructor === Object);//true
乍一看,constructor似乎完全可以应对基本数据类型和引用数据类型,都能检测出数据类型,事实上并不是如此,来看看为什么:
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn);
console.log(f.constructor===Array);
我声明了一个构造函数,并且把他的原型指向了Array的原型,所以这种情况下,constructor也显得力不从心了。
# 四、 Object.prototype.toString.call()
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply
来调用才能返回正确的类型信息。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引用
可以看出,Object.prototype.toString.call()可用于检测js所有的数据类型。所以说最好的方法是使用 Object.prototype.toString.call(参数) 这种方式,jQuery内部实际上就是采用这个方法进行数据类型检测的。