小结 javascript中的类型检测
先吐槽一下博客园的编辑器,太不好用了,一旦粘贴个表格进来就会卡死,每次都要用html编辑器写,不爽!
关于javascript的类型检测,早在实习的时候就应该总结,一直拖到现在,当时因为这个问题还出了线上bug。今天回顾《编写可维护的javascript》第八章“避免空比较”,里面详细说明了javascript中各种类型比较问题,现在想来当时的代码基本把所有的忌讳都犯了一遍,就那么上线了简直对不起党和人民。。。
类型检测 | |||||
类型 | 检测方法 | 检测对象 | 检测结果 | 缺点 | 备注 |
原始值 | typeof | 字符串 | string | ||
数字 | number | ||||
布尔值 | boolean | ||||
undefined | undefined | ||||
null | object | 引用类型的typeof结果为object,不能够起到检测的作用 | 检测null应用===或!== | ||
引用值 | instanceof | 内置类型:Object,Date,Error,RegExp | true/false | instanceof会检测原型链,每个对象都继承自Object | |
自定义类型及内置类型中的function、Array | true/false | frame A、B中分别定义构造函数Person,且两个Person完全相同。A中创建实例传入B中,则有, frameAPersonInstance instanceof frameAPerson //true frameAPersonInstance instanceof frameBPerson //false |
唯一的检测方法 | ||
typeof | function | function
//IE8以上 object //IE8及以下 |
针对IE8及以下版本,由于其未将DOM实现为内置的javascript方法,需使用 if("xxx" in document)(){};来检测DOM的方法 |
||
Array.isArray() | Array | true/false | ECMAScript5,适用于IE9+,FF4+,SF5+,O10.5+,Chrome | ||
Object.prototype.toString.call(value) === "[Object Array]" | true/false | 这种方法适用于所有内置对象,如JSON等 | |||
属性是否在对象中存在 | “XXX”in object | 属性 | 会深入检测实例及其继承的对象原型 | ||
hasOwnProperty() | true/false //IE8以上 无此方法 //IE8及以下 |
针对IE8及以下版本,由于DOM对象并非继承自Object,因此不包含此方法。所以需要检测方法是否存在: if(object.hasOwnProperty("related")){}; //针对非DOM对象 if("hasOwnProperty" in object && object.hasOwnProperty("related")){}; //不确定是否为DOM对象时 |
调用DOM对象的hasOwnProperty方法之前应先检测其是否存在!若已经知道对象不是DOM则可省略检测存在。 |
总的来说:
一、表总结
typeof通常用于基本类型(null除外)及function的检测;
instanceof通常用于自定义类型的检测;
准确的 引用类型 检测使用Object.prototype.toString.call(value) === "[Object Array]"等;
属性 的检测使用in和hasOwnProperty()。
二、补充
通过constructor进行类型检测,参考http://www.cnblogs.com/zhengchuyu/archive/2008/07/21/1247764.html
不过不推荐文中使用正则表达式match检测,正则会对性能有一定影响,并且正则的使用稍不留意就会给自己留下各种坑儿~~
三、性能
非IE系:typeof>.toString.call()>10*constructor
IE系列:typeof>constructor>.toString.call()