1.数据类型概述
在javascript中的每个值都有属于自己的数据类型,共有六种(新的es中又新增了symbol类型和bigInt类型,本文不涉及此种类型).
- 数值(Number): 都是浮点数,即使看起来是整数(20,2.0等)
- 字符串(String): 如"Hello World"
- 布尔值: true 和 false
- undefined: 表示未定义,例如变量声明但未赋值
- null: 从undefined中派生出来,表示一个空值或空指针.
其中,数值,字符串和布尔值称为基本数据类型或者原始数据类型等,undefined和null一般认为是两个特殊值.要注意的是null不属于object数据类型,即使通过typeof检测出object,这是历史遗留问题,说白了就是当年的bug.
object属于引用数据类型,是一种很复杂也很重要的类型,广义的object可以派生出数组(Array),函数(Function)和狭义的对象(类似{}的)子类型.
2.检测方法
有三种方法可以检测一个值的数据类型.
- typeof
- instanceof
- Object.prototype.toString()
1.typeof
typeof后面直接跟要检测的值,会返回类型的字符串描述.
typeof 123 //"number"
typeof "string" //"string"
typeof true //"boolean"
typeof undefined //"undefined"
typeof null //"object" 注意,这是bug
typeof {} //"object"
typeof [] //"object"
typeof function f(){} //"function"
很明显,这种方法不但没办法分辨出object的子类型,如数组Array.在检测null时还会误导.
2.instanceof
和typeof不同,instanceof能检测出数组
[] instanceof Array // true
123 instanceof Number // true
"string" instanceof String // true
....同上
看上去不错,但使用方法跟typeof不同,只能检测值是不是某一类型,而不能直接输出值的数据类型.我们还有更好的方法.
3.Object.prototype.toString.call()
Object.prototype.toString.call([])
//[object Array]
这个方法同instanceof一样能检测出各个类型,而且直接返回类型的字符串.可以说是结合了上文两者的好处.
但要注意的是:一定要使用Object原型对象上的toString而不是直接在值后调用toString.这样会把数组,数字,布尔值,函数转化为字符串,undefined和null直接报错,只有Object会返回[object Object].
此方法直接返回的值看起来不太直观,我们可以配合正则封装成一个函数,直观地输出值的类型
function _typeOf(value) {
const kind = Object.prototype.toString.call(value);
return kind.match(/\[object (\w+)\]/)[1].toLowerCase();
}
_typeOf(123) //number
_typeOf("string") //string
_typeOf(true) //boolean
_typeOf(undefined) //undefined
_typeOf(null) //null
_typeOf([]) //array
_typeOf({}) //object
_typeOf(function f(){}) //function
_typeof(/123/) //regexp