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

浙公网安备 33010602011771号