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