一、typeof
typeof,字面上的意思就是类型,用来判断数据的类型,返回的是字符串。
console.log(typeof 123); // number
console.log(typeof 'abc'); // string
console.log(typeof true); // boolean
console.log(typeof Symbol()); // symbol
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function (){}); // function
对于前六种基本数据类型,除了null,其他的使用typeof都能正确的判断出来,null那个是js的一个bug,对于null可以使用严格相等 === 来判断。对于引用类型,就不能判断具体是哪种类型的值了,除了函数类型,typeof也可以正确判断函数类型。
二、instanceof
instanceof,字面上的意思就是实例,右边这个对象有没有出现在左边的原型链之上,返回的是布尔值
let Foo = function (){}
let Bar = function (){}
Foo.prototype = new Bar();
let foo = new Foo();
console.log(foo instanceof Foo); // true
console.log(foo instanceof Bar); // true
但是对于数组和函数,instanceof也不能很好的判断
console.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log(Foo instanceof Function); // true
console.log(Foo instanceof Object); // true
原因是对于array和function,instanceof在查找原型链时,发现这Object也在它们的原型链上,返回的就是true了。还有一点就是,instanceof的左边如果是基本数据类型,那也不能判断的,比如:123 instanceof Number返回的就是false。
三、通用类型检测
以上两种方法都有各自的局限性,那么有没有通用的方法可以判断一个数据的类型呢?其实是有的,在js里,可以使用Object.prototype.toString.call(),这个方法返回的是一个特定格式的字符串
Object.prototype.toString.call(123); // [object Number]
Object.prototype.toString.call('abc'); // [object String]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(Symbol()); // [object Symbol]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(function() {}); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(/[a-z]]/); //[object RegExp]
可以看出这个方法很好的判断出了数据的类型,其实每种数据类型都有toString方法,为什么不像[].toString()这样用呢?是因为这些toString方法都被重写了,功能变的不一样了,Object.prototype上的toSting方法才是返回数据的类型。