Skip to content

数据类型检测的方式有哪些?

typeof

typeof能解决基本类型的类型检测,但是null比较特殊,它的类型为object

js
typeof 'str' === 'string'  //true
typeof 1234 === 'number'  //true
typeof true === 'boolean'  //true
typeof null === 'object'  //true

typeof对数组和对象的判断结果都为object

js
typeof [] === 'object'  //true
typeof {} === 'object'  //true

function fn(){}
typeof  fn === 'function'  //true

其中数组对象null都会被判断为object,其他判断都正确。

instanceof

instanceof是判断某值是否为某个构造函数的实例,内部是通过原型链去寻找是否存在该类型的原型,因此对于引用类型值的判断是Ok的

js
{} instanceof Object  //true
[] instanceof Array  //true
[] instanceof Object  //true

function fn(){}
fn instanceof Function  //true
fn instanceof Object  //true

但对基本类型就不怎么适用了

js
(2) instanceof Number //false
(true) instanceof Boolean //false
('str') instanceof String  //false

constructor

constructor我们应该都清楚,其是构造函数的[[prototype]]属性的一个属性,这个属性值为构造函数本身

js
function Person(){

}
let p = new Person()
p.constructor === Person //true

WARNING

当然手动改变构造函数的[[prototype]]就寄了

js
function Animal(){

}
Person.prototype = new Animal()
let p2 = new Person()
p2.constructor === Person //false
p2.constructor === Animal //true

因此constructor能够判断某值的类型,也能够访问实例对象的构造函数,但是原型被改则类型判断会出问题。

Object.prototype.toString.call()

会得到'[object xxx]'这种格式文本,再通过正则匹配获取正确的类型

javascript
var a = Object.prototype.toString;
 
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

TIP

Q:为何不能直接使用Object.toString()?

A:因为例如Function、Array这些构造函数(为Object的实例)的toString方法是被重写过了(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),因此调用不到在Object上原型的toString方法(返回对象的具体类型)。