判断数据类型一直是面试的高频考点,之前我个人最常用的方法有两个typeof以及instanceof,还有一个之前用的很少Object.prototype.toString.call()。这三个方法都有自己的局限性,这次放松总结一下。
typeof
typeof基本上可以判断基本数据类型,
可以准确判断数据类型有undefined,Number,String,Boolean,Function,
不能准确判断的数据类型有null,Object,Array,这三种数据类型返回的值都为Object,引用数据类型可以用Object.prototype.toString.call()和instanceof弥补
// 可以准确判断的类型
console.log( typeof undefined ); // undefined
console.log( typeof 1 ); // number
console.log( typeof 'aaa' ); // string
console.log( typeof false ); // boolean
let fn = function(){}
console.log( typeof fn ); // function
// 不能准确判断的数据类型
console.log( typeof null ); // object
console.log( typeof {name:'zb'} ); // object
console.log( typeof [1,2,3] ); // object
Object.prototype.toString.call()
这是一个接近六边形战士的函数,适用于基本数据类型和引用数据类型,三个方法中唯一一个正确判断null的方法。
唯一不足是不能判断一个对象是不是自定义构造函数的实例化对象,可用instanceof弥补
// 正确判断基本数据类型
console.log( Object.prototype.toString.call(undefined) ); // [object Undefined]
console.log( Object.prototype.toString.call(null) ); // [object Null]
console.log( Object.prototype.toString.call(1) ); // [object Number]
console.log( Object.prototype.toString.call('aa') ); // [object String]
console.log( Object.prototype.toString.call(false) ); // [object Boolean]
// 正确判断引用数据类型
console.log( Object.prototype.toString.call({name:'zb'}) ); // [object Object]
console.log( Object.prototype.toString.call([1,2]) ); // [object Array]
console.log( Object.prototype.toString.call(function(){}) ); // [object Function]
// 唯一的弱点,对于自定义构造函数
let Person = function(name){
this.name = name
}
let zb = new Person('zb')
console.log( Object.prototype.toString.call(zb) ); // 不能判断zb是不是Person构造函数的实例化对象
instanceof
typeof大体可以判断基本数据类型(null除外),对于引用数据类型的判断很乏力,所以用instanceof弥补typeof
Object.prototype.toString.call()适用基本数据类型和引用数据类型,唯一不足是不能判断一个对象是不是自定义构造函数的实例化对象,这里instanceof可以弥补。
instanceof主要用于判断引用数据类型。判断的原理A instanceof B 看B的显示原型在不在A的隐式原型链上
// 对于基本数据类型不适用
// 对于引用数据类型
console.log( [1,2] instanceof Array ); // true
console.log( [1,2] instanceof Object ); // true,因为数组也是对象的一种特殊形式
console.log( {name:'zb'} instanceof Object ); // true
console.log( null instanceof Object ); // false
let fn = function(){}
console.log( fn instanceof Object ); // true,因为函数也是对象的一种特殊形式
// 判断一个对象是不是自定义构造函数的实例化对象
let Person = function(name){
this.name = name
}
let zb = new Person('zb')
console.log( zb instanceof Person ); // true
三个方法没有说哪个是非常完美的,都带有一些瑕疵,三个方法相互补充使用。