从Underscore源码看JavaScript数据类型判断

Underscore是一个很是实用的JavaScript库,提供许多编程时须要的功能的支持,他在不扩展任何JavaScript的原生对象的状况下提供不少实用的功能。编程

结合Underscore中关于数据类型判断的函数源码,看看如何准确、高效地判断JavaScript中的数据的类型。数组

JavaScript定义了6种数据类型:五种原始类型(Null、Undefined、Boolean、Number、String)与Object。浏览器

 

Null表示准备用来保存对象,尚未真正保存对象的值。从逻辑角度看,Null值表示一个空对象指针。因此typeof Null结果为object。函数

1 _.isNull = function(obj){
2     return obj ===null;// 源码中是三等号。因此若是obj是undefined,返回的是false
3 };

 

Undefined表示变量声明但未初始化时的值。性能

1 _.isUndefined = function(obj){
2     return obj === void 0;// void 0 也能够写做void(0),void的做用是计算表达式,因为undefined在es3中不是关键字,会被改写,因此使用返回undefined的函数来代替(用空函数也能够返回undefined)。
3 };

另外一个方法(typeof)会存在问题:未声明的变量使用typeof结果也为'undefined'。es5

 

Boolean:spa

1 _.isBoolean = function(obj){
2     return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
3 };

照理应该判断toString.call(obj) === '[object Boolean]'就能够了,加上obj === true和obj === false判断提高性能。prototype

 

Number、String:指针

1 _['is' + name] = function(obj){
2     return toString.call(obj) ===='[object'+ name +']';// 使用原生的toString方法,即Object.prototype.toString
3  };

new Number()、new String()方法建立的数据是包装对象,使用typeof结果为'object'。判断是否为数字、字符串使用Object.prototype.toString.call()最保险。上面的Boolean值判断也考虑了这一点。Number类型还包括一个NaN(Not a Number),先判断是否为Number类型,再判断是否等于它本身:code

1 _.isNaN = function(obj){
2     return _.isNumber(obj) && obj !==+obj;// '+'放在变量前面为了把var num = new Number()这种也归为NaN
3 };

 

Object:

 

1 _.isObject = function(obj){
2     var type = typeof obj;
3     return type === 'function' || type === 'object' && !!obj;
4 };

先用typeof判断数据类型。函数也属于对象,可是因为typeof null也是'object',因此用!!obj来区分这种状况。

 

1 _.isArray = nativeIsArray || function(obj){
2     return toString.call(obj) === '[object Array]';
3 };

判断obj是不是数组。若是浏览器中有isArray(es5)就用原生的判断方法。

 

Arguments、Function、Date、RegExp、Error:

1 _['is' + name] = function(obj){
2     return toString.call(obj) ===='[object'+ name +']';
3  };

 

综上,Object.prototype.toString.call()的方法最为适用与准确,但部分数据类型判断仍是有更好的简单方法。

相关文章
相关标签/搜索