1、typeof
所有的值在内存中都是按照二进制存储的
/*
* 检测数据类型1:typeof
* 返回结果都是字符串
* 字符串中包含了对应的数据类型 "number"/"string"/"boolean"/"undefined"/"symbol"/"object"/"function"
*
* 【局限性】
* typeof null => "object" null不是对象,它是空对象指针
* 检测数据或者正则等特殊的对象,返回结果都是"object",所以无法基于typeof判断是数据还是正则
*/
// console.log(typeof []); //=>"object"
// console.log(typeof typeof []); //=>"string"
2、instanceof / 3、constructor
/*
* 检测数据类型2/3:instanceof / constructor
* 检测某个实例是否属于这个类
* 他检测的底层机制:所有出现在其原型链上的类,检测结果都是TRUE
* 【局限性】
* 由于可以基于__proto__或者prototype改动原型链的动向,所以基于instanceof检测出来的结果并不一定是准确的
* 基本数据类型的值,连对象都不是,更没有__proto__,虽说也是所属类的实例,在JS中也可以调取所属类原型上的方法,但是instanceof是不认的
*/
// console.log(12 instanceof Number); //=>false
// console.log(new Number(12) instanceof Number); //=>true
// console.log([] instanceof Array); //=>true
// console.log([] instanceof Object); //=>true
// function Fn() {}
// Fn.prototype.__proto__ = Array.prototype;
// let f = new Fn();
// //=>原型链:f -> Fn.prototype -> Array.prototype -> Object.prototype
4、Object.prototype.toString.call
/*
* 检测数据类型4:Object.prototype.toString.call([value]) / ({}).toString.call([value])
* 不是用来转换为字符串的,而是返回当前实例所属类的信息
* 格式:"[object 所属类信息]"
* "[object Object/Array/RegExp/Date/Function/Null/Undefined/Number/String/Boolean/Symbol...]"
* 这种方式基本上没有什么局限性,是检测数据类型最准确的方式
*/
// Number/String/Boolean/Symbol他们的原型上都有:
// =>toString:转化为字符串
// =>valueOf:返回原始值
// Array/RegExp/Function等内置类的原型上都有
// =>toString:转化为字符串
// Object的原型上
// =>toString:返回当前实例所属类的信息
// =>valueOf:返回原始值