如何正确判断JS
的数据类型
说道判断数据类型,大多数人可能会想到typeof
和instanceof
那么typeof
和instanceof
真的能够准确的判断数据类型吗?他们有那些局限呢
一.typeof
var a = typeof 1; --------> number
var a1 = typeof '1'; --------> string
var a2 = typeof false; --------> boolean
var a3 = typeof null; --------> object
var a4 = typeof undefined; --------> undefined
var a5 = typeof []; --------> object
var a6 = typeof {}; --------> object
var a7 = typeof Symbol(); --------> symbol
var a8 = typeof function(){}; --------> function
var a9 = typeof NaN; -------> number
console.log(a,a1,a2,a3,a4,a5,a6,a7,a8,a9)
根据结果可以看到typeof
在判断null,[],{}
判断出来都是object
其中typeof null
为object
为什么会出现这种情况呢?因为在 JS
的最初版本中,使用的是 32 位系统,为了性能考虑使用低位存储了变量的类型信息,000
开头代表是对象,然而 null
表示为全零,所以将它错误的判断为 object
。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
二.instanceof
function Animal(){ }
var dog = new Animal()
var a = 1 instanceof Number -------> false
var a1 = {} instanceof Object -------> true
var a2 = [] instanceof Array -------> true
var a3 = function(){} instanceof Function -------> true
var a4 = dog instanceof Animal -------> true
console.log(a,a1,a2,a3,a4)
根据结果可以看到instanceof
可以判断复杂数据类型,无法判断基本数据类型,而且数组和对象判断出来都是Object
instanceof
是通过原型链来判断的,如果想要手写实现instanceof
,可以看我的另外一篇文章:手动实现instanceof
三.Object.prototype.toString.call()
var a = Object.prototype.toString.call({}); --------------> [object Object]
var a1 = Object.prototype.toString.call([]); ------------->[object Array]
var a2 = Object.prototype.toString.call(1); --------------> [object Number]
var a3 = Object.prototype.toString.call(false); --------------> [object Boolean]
var a4 = Object.prototype.toString.call(undefined); --------------> [object Undefined]
var a5 = Object.prototype.toString.call(null); --------------> [object Null]
var a6 = Object.prototype.toString.call('判断类型'); --------------> [object String]
var a7 = Object.prototype.toString.call(function(){}); --------------> [object Function]
var a8 = Object.prototype.toString.call(Symbol()); --------------> [object Symbol]
var a9 = Object.prototype.toString.call(NaN); --------------> [object Number]
console.log(a,a1,a2,a3,a4,a5,a6,a7,a8,a9)
控制台打印结果:
返回的结果是一个字符串,object
后面代表的是判断的数据类型
根据结果可以看到Object.prototype.toString.call()
可以准确的判断数据的类型,不管是基本数据类型还是引用数据类型
推荐使用Object.prototype.toString.call()
来判断