JavaScript 是一种弱类型(或称动态类型)语言,即变量的类型是不确定的。所以在特定场景下对数据类型的判断,就显得尤为重要,可保证我们程序的稳定性。
js中存在两类数据类型,基本数据类型和引用数据类型
1. 基本数据类型
JavaScript有七种基本数据类型
- number
- string
- boolean
- symbol
- bigint
- undefined
- null
2. 引用数据类型
除了上面的七种数据类型,其他的就是引用数据类型
- Object
- Array
- Funciton
- Date
- RegExp
- ...
3. 判断方法
有三种方法判断变量的数据类型
- typeof
- instanceof
- Object.prototype.toString.call()
3.1 typeof
typeof主要用于基本数据类型的判断
typeof 1 // 'number'
typeof "1" // 'string'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof 1n // 'bigint'
typeof undefined // 'undefined'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof function() {} // 'function'
可以看出typeof对于基本数据类型基本都可判断出来。null是个特例,可通过val === null进行判断。
(typeof null === 'object'其实是js的一个bug,不代表null就是引用数据类型,并且null本身也不是对象)
原理:不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息。
3.2 instanceof
instanceof主要用于引用数据类型的判断
({}) instanceof Object // true
([]) instanceof Array //或 Object // true
(function(){}) instanceof Function //或 Object // true
(/aa/g) instanceof RegExp // true
(new Date()) instanceof Date // true
let Person = function() {}
let jhon = new Person()
jhon instanceof Person // true
let newStr = new String('xxx')
newStr instanceof String // true
let str = 'xxx'
str instanceof String // false
可以看出instanceof对于引用数据类型基本都可判断出来。判断{}是个特例,可通过Object.prototype.toString.call(obj)==='[object Object]'进行判断。
(因为{}/[]/function instanceof Object都为true,所以Object并不能判断出该值的数据类型是{}。此外,对于基本数据类型的判断直接返回false)
原理:instanceof 运算符检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
3.3 Object.prototype.toString
通用的判断数据类型方法,调用该方法,统一返回[object Xxx]格式的字符串
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(1n) // "[object BigInt]"
Object.prototype.toString.call(Symbol()) // "[object Symbol]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
原理:获取this指向的那个对象的[[Class]]属性的值,返回[object className] 格式字符串
3.4 其他方法
constructor判断、Array.isArray()判断数组、Number.isNaN判断NaN,可作为判断补充
4. 总结
typeof可判断大部分基本数据类型,基本数据类型null不可判断,引用数据类型function可判断。instanceof可判断大部分引用数据类型,{}不可判断。Object.prototype.toString可判断所有数据类型。
5. 封装通用类型判断工具
// @return
// number | string | boolean | bigint | symbol | undefined | null
// object | array | function | date | regexp | ...
function getTypeOf(val) {
if (val === null) return "null";
if (typeof val !== "object") { // 减少因tostring装箱操作,产生的临时对象
return typeof val;
} else {
return Object.prototype.toString
.call(val)
.slice(8, -1)
.toLocaleLowerCase();
}
}
参考文档