細說JS的類型判斷
眾所周知,JS是一門弱類型的語言,類型檢查不嚴格,那麼準確的去判斷一個數據的類型就成了一個比較重要的問題。
typeof
MDN文檔上解釋typeof為:表示未經計算的操作數的類型。
typeof(1) // number typeof(str) // string typeof([]) // object typeof(true) // boolean typeof({}) // object typeof(null) // object typeof(undefined) // undefined typeof(function(){}) // function typeof(Symbol()) // symbol typeof(NaN) // number
上面的問題在於對Array和null,我們往往想要得到的是『Array』和『null』,但實際上是『object』
利用constructor
因為每個數據類型實際上是由一個函數的實例,而每個實例的構造函數執行創建這個實例的函數,所以可以從這點出發判斷數據的類型
const num = 1; num.constructor === Number // true const num1 = NaN; num1.constructor === Number // true str.constructor === String // true true.constructor === Boolean // true [].constructor === Array // true const obj = {}; obj.constructor === Object //true const s = Symbol(1) s.constructor === Symbol // true const fun = function(){} fun.constructor === Function // true
這種方法大部分類型還是能判斷出來,只不過由於Null和undefined的特殊性導致這兩個類型用這種方法無法判斷出來
利用 Object.prototype.toString.call
Object.prototype.toString.call(1).slice(8,-1) // Number Object.prototype.toString.call(str).slice(8,-1) // String Object.prototype.toString.call([]).slice(8,-1) // Array Object.prototype.toString.call(true).slice(8,-1) // Boolean Object.prototype.toString.call(function(){}).slice(8,-1) // Function Object.prototype.toString.call({}).slice(8,-1) // Object Object.prototype.toString.call(null).slice(8,-1) // Null Object.prototype.toString.call(undefined).slice(8,-1) // undefined Object.prototype.toString.call(Symbol(1)).slice(8,-1) // Symbol
這種方法對於所有基本的數據類型都能進行判斷,即使是null和undefined 。並且,Array和null也明細區分了出來了,而不再是typeof出來的Object
利用instanceof
mdn對instanceof的解釋是用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。
Number(1) instanceof Number; //false str instanceof String; //false [] instanceof Array; //true [] instanceof Object; //true const obj = ; obj instanceof Object; //true const s = Symbol(1) s instanceof Symbol; //false const fun = function(){} fun instanceof Function; //true fun instanceof Object; //true
從上面可以看出,因為 instanceof 的特性,所以在準確判斷數據類型方面還是有很大的缺陷的
特定數據類型的判斷
這裡主要是說某些數據類型自帶的判斷方法,如數組中的Array.isArray,isNaN,
const arr = []; Array.isArray(arr) //true const num = NaN; isNaN(num) // true
自定義類型的判斷
對於自己構造的類生成的數據類型如何判斷,
function AA(){} let aa = new AA() typeof(aa) // object aa在這裡實際上是個對象 aa.constructor === AA // true 可以判斷出為AA這個類型 Object.prototype.toString.call(aa).slice(8,-1) // Object 同typeof一樣,只能判斷出為對象類型 aa instanceof AA //true //原型繼承 function BB(){} BB.prototype = new AA(); let bb = new BB() typeof(bb) // object bb在這裡實際上是個對象 bb.constructor === BB // false bb.constructor === AA // true //這裡的構造函數實際上為AA Object.prototype.toString.call(bb).slice(8,-1) // Object 同typeof一樣,只能判斷出為對象類型 bb instanceof AA; //true bb instanceof BB; //true
總結
綜上所述,每種方法都有其特點蘊含其中,在判斷數據類型時,可以根據特定的場景選擇最恰當的方法進行判斷篩選
推薦閱讀:
※jQuery速覽(一)
※有沒有推薦設UI計師學的代碼,例如xcode,JQ等輕體量上手快的IDE,主要為了實現動效和前端對接?
※jQuery速覽(二)
※為什麼有很多人明明基礎都不會,卻一直在討論jQuery?
※為什麼一些大公司願意無償提供CDN服務?