JavaScript 資料類型判斷
JavaScript 的資料類型分為兩類:原始類型(基本類型)和物件類型(參考型別)。原始類型包括數字、字串和布爾值,另外有兩個特殊的原始值:null 和 undefined,除此之外的都是對象。對象還包括兩種特殊的對象:數組和函數。 下面所有代碼錶達式如果傳回值為 true 表示判斷成立,否則不成立,變數 obj 表示需要判斷的值。 通用方法 使用 typeof 運算子判斷資料類型可以使用 typeof 運算子,傳回值是一個代表資料類型的字串(注意是字串,而且是小寫): typeof 1 // 'number'typeof 'abc' // 'string'typeof false // 'boolean'typeof undefined // 'undefined'typeof null // 'object'typeof {x: 1} // 'object'typeof [1, 2, 3] // 'object'typeof function() {} // 'function'typeof 運算子可以有效判斷數字、字串、布爾值和 undefined 等原始類型,不過在面對數組和對象時就無能為力了。 借用 Object.prototype.toString() 方法借用 Object.prototype.toString() 方法可以得到一個表示對象的類型的字串: var toString = Object.prototype.toString;toString.call('abc') // '[object String]'toString.call(true) // '[object Boolean]'toString.call([]) // '[object Array]'toString.call({}) // '[object Object]'toString.call(/./) // '[object RegExp]'toString.call(new Date) // '[object Date]'toString.call(Math) // '[object Math]'使用該方法可以有效判斷數組、函數、日期、Regex等物件類型(參考型別)。在 ECMAScript 5 中還可以用這個方法來判斷 null和 undefined: toString.call(null) // '[object Null]'toString.call(undefined) // '[object Undefined]'下面是一些特殊情況。 原始類型(基本類型) 數字使用 typeof 運算子可以判斷任一數字、NaN 或者 Infinity: typeof NaN // 'number'typeof Infinity // 'number'如果要排除 NaN 和 Infinity 可以使用 isFinite() 方法,不過 isFinite() 方法試圖將一些非數字類型轉換為數字,因此需要雙重保險: typeof obj === 'number' && isFinite(obj)上面的運算式如果返回為 true 則保證了變數 obj 是數字類型的同時不是 NaN 或者 Infinity,畢竟我們不希望這兩個特殊數值參與數學運算。ECMAScript 6 增加的 Number.isFinite() 方法有同樣效果。 整數判斷一個數是整數並且在安全範圍內,利用整數取整後還是與自身相等的特點: typeof obj === 'number' && isFinite(obj) && obj > -9007199254740992 && obj < 9007199254740992 && Math.floor(obj) === objNaN全域的 isNaN() 方法也試圖將一些非數字類型隱式轉換為數字,如果轉換成功,它會認為這個值是一個數字,否則會認為這是一個 NaN: isNaN(NaN) // trueisNaN(0/0) // true 0 除以 0 的結果為 NaNisNaN('1') // false 字串 '1' 可以隱式轉換為數字 1isNaN(true) // false 布爾值 true 可以隱式轉換為數字 1isNaN([]) // false 空數組可以隱式轉換為數字 0isNaN(Infinity) // falseisNaN('abc') // trueisNaN(undefined) // true字串 'abc' 和 undefined 都不能隱式轉換為一個數字,所以被判斷為是一個 NaN。 NaN 是一個特殊數值,它不等於任何值,甚至不等於它自己,因此判斷一個值為 NaN 的最好方式是判斷它是一個數字類型同時不等於自身: typeof obj === 'number' && obj != +objECMAScript 6 增加的 Number.isNaN() 方法更好地解決了這個問題,只有值為 NaN 的時候才會返回 true: Number.isNaN(NaN) // trueNumber.isNaN(Number.NaN) // trueNumber.isNaN(0/0) // trueNumber.isNaN(Infinity) // falseNumber.isNaN('abc') // falseNumber.isNaN(undefined) // false可以看出 Number.isNaN() 方法和 isNaN() 方法是不一樣的。Number.isNaN() 方法僅用於判斷是否是特殊值 NaN。 布爾值布爾值不是 true 就是 false,可以使用 typeof 運算子,也可以像下面這樣判斷: obj === true || obj === falseUndefined在 ECMAScript 3 中 undefined 是可讀寫的,所以直接與 undefined 作比較返回的結果不一定是準確的,像這樣 var undefined = 1 在有些實現中是可以改變其值的,此時再與之做比較得到的結果就有點出人意料了,通常情況下還是使用 typeof 運算子來判斷: typeof obj === 'undefined'不過使用 typeof 運算子有一個不好的地方是不能區分未定義的變數和值為 undefined 的變數(兩者還是有區別的),另外一種方式是使用 void 運算子,因為它的運算結果總是返回 undefined: obj === void 0Null使用 typeof 運算子判斷 null 將會返回 'object',這明顯不是想要的,所以最好的方式是直接與 null 值進行比較: obj === null這裡必須使用 ===,因為 undefined == null 也會返回 true。 存在判斷對值為 null 或 undefined 的變數讀取屬性時會引發錯誤,因此有時候需要做存在判斷,簡單地使用 if 語句來判斷,會將那些可以隱式轉換為 false 的值也一概排除掉了,比如數字0、Null 字元串、空數組之類的,它們都可以隱式轉換為 false,因為 undefined == null 會返回 true,而和其它任何非 null 或者 undefined 的值比較都會返回 false,所以更好的辦法是直接與 null 值做比較: if (obj != null) { obj.property;}這樣就可以判斷變數 obj 既不是 undefined 也不是 null,或者像下面這樣判斷: typeof obj !== 'undefined' && obj !== null通過存在判斷才可以放心使用 . 文法擷取屬性。 物件類型(參考型別) 對象要區別 null 和其它對象可以像下面這樣判斷,因為 null 值可以隱式轉換為 false: obj && typeof obj === 'object'這樣判斷就可以把 null 給排除掉,變數 obj 是對象或者數組或者其它對象(不包括函數)。下面是另外一種方法: obj === Object(obj)使用 Object() 方法如果傳入的參數不是對象將會被轉換為對象,否則,只是簡單地將傳入的參數返回。該方法可以判斷所有對象,包括函數。 數組判斷數組的方法: Object.prototype.toString.call(obj) === '[object Array]'ECMAScript 5 增加了數組檢測的原生方法: Array.isArray(obj)函數雖然 typeof 運算子將函數特別對待了,但是使用 typeof 運算子在有些實現中不是函數的也會返回 'function',因此還是使用如下方法來判斷函數: Object.prototype.toString.call(obj) === '[object Function]'Regex使用 typeof 運算子判斷Regex,一般都會返回 'object',不過也有一些實現會返回 'function',所以,還是借用 Object.prototype.toString 方法來判斷: Object.prototype.toString.call(obj) === '[object RegExp]'