从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'。

 

Boolean:

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判断提升性能。

 

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类型,再判断是否等于它自己:

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()的方法最为适用与准确,但部分数据类型判断还是有更好的简单方法。

posted @ 2016-03-23 14:08  SKYWLAN  阅读(275)  评论(0)    收藏  举报