前言
在JS中常见常用的数据类型检测方法有下面的四种,每种检测方法都不是特别完美的,各自都存在一些问题,检测范围都有局限性,用的时候,要灵活运用,根据各自的特点来选用符合的合适的检测方法,以达到目的。
typeof
主要用来检测JS的基本类型值,比较好用,检测对象类型时不太好用,返回值是字符串类型的,字符串里面是检测出来的数据类型,而且首字母是小写
对象 和 null 用 typeof 检测返回的都是 'object'
- typeof 直接在计算机底层基于数据类型的值(二进制)进行检测
- tyepof null "object" 对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象,null也被叫做空指针对象
- typeof 普通对象/数组对象/正则对象/日期对象 都返回 "object",无法检测出具体是对象类型中的哪种对象
console.log(typeof 1)
//=> "number"
----------------------------
console.log(typeof typeof 1)
//=> "string"
-----------------------------
console.log(typeof null)
//=> "object"
-----------------------------
console.log(typeof [])
//=> "object"
注意: ES6之前存在不符合暂时性死区的问题
typeof a //=> undefined
//在a没有被声明的情况下用typeof检测a竟然是undefined,竟然没有报错
//暂时性死区要求变量在声明之前是不可以被使用的,会报错
//这里不符合暂时性死区的要求
instanceof
instanceof 检测当前实例是否属于某个类,返回值是布尔类型 true 或者 false
- instanceof 检测当前实例是否属于这个类的
- 底层机制:只要当前类出现在实例的原型链上,结果都是true,不知道具体的父类
- 由于我们可以肆意的修改原型的指向,所以检测出来的结果是不准的
- 不能检测基本数据类型,基本值不能拿它检测,如果想要检测基本类型值,那也必须是使用构造函数的形式创建出来的基本数据类型值,才可以使用instanceof进行数据类型检测
console.log([] instanceof Array)
//=> true
-------------------------------
console.log(1 instanceof Number)
//=> false
-------------------------------
console.log(new Number(1) instanceof Number)
//=> true
constructor
- 用起来看似比instanceof还好用一些(基本类型支持的)
- constructor可以随便改,所以也不准
let abc = 123;
abc.constructor //=>ƒ Number() { [native code] }
let ary=[];
ary.constructor === Array;//=> true
**注意:**如果当前类的原型重定向了,那就不准了,不过内置类不允许重定向,内置类原型里面的方法可以随便改
toString.call(value)
这个方法是Object.prototype.toString.call(),可以简写为toString.call(),这种检测方法是四种检测方法里面最接近完美的检测方法,能检测js的各种内置类,不过缺点也是只能检测js的内置类
注意: 这里的toString是Object原型上的方法,要与xxx.toString()转字符串的方法要区分开
举个例子:
let ary = [1,2,3,4];
Object.prototype.toString.call(ary);//=> "[object Array]"
let ary = [1,2,3,4];
ary.toString();//=> "1,2,3,4"
- 标准检测数据类型的办法:Object.prototype.toString不是转换为字符串,是返回当前实例所属类的信息
- 标准检测的办法:
检测结果是:'[object 当前的类]'
"[object Number/String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Function]"