目录
- typeof
- instanceof
- constructor
- Object.prototype.toString.call
typeof
- 语法:typeof [val],返回当前值val对应的数据类型(返回结果是一个字符串)
- 检测基本类型——还是蛮准的,除了一个BUG:typeof null === ‘object’
- 检测引用类型——并不能细分具体的对象类型(如数组对象、正则对象等)
instanceof
本意是检测某个值是否属于某个类(是否是某个类的实例)
- 语法:[val] instanceof [class]
- 优势:相对于typeof,可以细分对象中的具体类型啦。
- 局限:
- 无法检测基本数据类型
- 由于instanceof的检测原理是:只要原型链上出现了这个类就返回true,所以有时也不是非常准确。而且原型指向可以任意改变!
- 第二个例子中,我们把一个和数组八竿子打不着的函数Fn,强制改变了原型指向,结果它的一个实例就变成了数组的实例???( 小朋友的很多问号 ),这也太容易被改变了吧,一点原则都没有!所以说,这种方法还是不怎么靠谱。
与instanceof类似,也不是专业的,也存在和前者同样的弊端——原型指向可以随意改变(而且重定向之后constructor很容易就被丢弃掉!)
好在它相比instanceof还是多那么一点点优势,检测准确性稍高一点。
- 它可以检测基本类型值啦!
- 值的constructor属性指向它的直接所属类,而不是原型链上的所有类都可以。
我们的终极大法来了!这个方法没有缺点!
toString这个方法好像满大街都是,你可能有很多❓:检测数据类型怎么和“转换为字符串”扯上关系了呢?
In fact,Object基类的原型上的toString方法是个独特的存在(虽然都叫一个名字),它是用来检测数据类型的。调用call方法是希望将toString函数中的this强制修改为你要检测的那个值。简单起见,也可以把这种方法简写为({}).toString.call([val])
,同样都会找到Object原型的toString方法。
测试一下:
解释两个问题:
- 得到的结果是一个字符串,字符串中看样子像一个数组( 但不是数组!),前面的object是统一的,而后面则是值所属的类。
({}).toString.call([val])
前面的空对象为啥要加括号?在JS中{}
有多种含义,不加()会引起歧义而报错。
以上四种方法各有千秋,比较常用的是typeof
和({}).toString.call
两种,有兴趣的话可以自己尝试封装一个检测数据类型的万能方法~可以参考jQuery中的封装方法,有时间我会再更新到这里哟!