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()的方法最爲適用與準確,但部分數據類型判斷仍是有更好的簡單方法。