js中,根據存儲的方式不一樣(參見文末鏈接), 數據能夠劃分爲如下兩大類型:數組
string, number, boolean, undefined, null, symbol函數
Object (Array, Function, RegExp, Date)post
判斷數據的所屬類型此處列舉四種方法,並對每種方法使用的範圍以及限制進行說明.若是對原型鏈還不熟悉的同窗,請先閱讀相關的原型鏈知識(見文末)ui
typeof
通常僅用於判斷原始類型(不包含null),返回值爲該類型的字符串this
console.log(typeof 'str'); // string
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof Symbol()); // symbol
複製代碼
注意:
typeof
不能用於判斷原始類型中的null
以及引用類型object
,結果都會返回字符串object(Function
類型除外,結果會返回function,但在在 IE 6, 7 和 8 上則返回object)spa
console.log(typeof null); // object
console.log(typeof {}); // object
console.log(typeof alert); // function
console.log(typeof []); // object
console.log(typeof new RegExp()); // object
console.log(typeof new Date()); // object
複製代碼
constructor
主要是利用原型上的prototype.constructor
指向實例的構造函數來進行判斷的prototype
先定義一個構造函數Animal
, 並new
一個實例dog
3d
const Animal = function (name) {this.name = name}; // 聲明一個構造函數
let dog = new Animal('dog'); // 生成實例dog
複製代碼
聲明Animal
函數的同時js會在Animal
上掛載一個prototype
對象,同時在prototype
對象上會自動生成一個constructor
屬性並指向構造函數Animal
,至關於:
Animal.prototype.constructor === Animal // true
,根據原型鏈的查找原則, console(dog.prototype) // Animal
因此利用構造函數原型上的constructor
屬性能夠判斷當前實例是否爲當前構造函數的實例,進而肯定數據所屬類型:code
console.log('1'.constructor === String); // true
console.log(new Number(1).constructor === Number); // true
console.log(true.constructor === Boolean); // true
console.log(alert.constructor === Function); // true
console.log([].constructor === Array); // true
console.log(new Date().constructor === Date); // true
複製代碼
注意:對象
null
,undefined
是無效的對象,所以是不會有constructor
存在的,這兩種類型的數據須要經過其餘方式來判斷。- 函數的 constructor 是不穩定的,這個主要體如今自定義對象上,當開發者重寫 prototype 後,原有的 constructor 引用會丟失,constructor 會默認爲 Object
用 constructor
判斷類型的限制過多且不許確,容易出錯,少用,或者不用!
與 typeof
和 constructor
不一樣, instanceof
通常用於判斷引用類型,返回值爲布爾值, 例如:
[] instanceof Array // true
instanceof
是經過判斷當前實例的原型與構造函數的原型是否爲同一對象,進而肯定當前數據的類型,這樣講或許不夠明瞭,咱們簡單實現一下 instanceof
const self_instanceof = function (instance, constructor) {
let instance_proto = instance.__proto__;
let constructor_proto = constructor.prototype;
while(true) {
// 找到終點返回false
if (instance_proto === null) {return false};
// 找到返回true
if (instance_proto === constructor_proto) {return true};
// 當實例與構造函數原型不相同, 沿着原型鏈繼續向上查找
instance_proto = instance_proto.__proto__;
}
}
console.log([] instanceof Array) // true
console.log(self_instanceof([], Array)) // true
複製代碼
當一個頁面存在多個
iframe
時,也就是存在多個全局變量window
,instanceof
的判斷會被來自不一樣的iframe的數據所幹擾,致使不可信
假設:頁面pageA
經過iframe
內嵌了頁面pageB
, 此時pageB
傳遞了一個數組 let arrB = []
到頁面 pageA
, 若在pageA
使用instanceof
判斷數組arrB
會出現 arrB instanceof Array // false
主要緣由是由於 arrB
是由pageB
上的Array
構造出來的
要避免這種問題可使用Es6
提供的數組靜態方法 Array.isArray
, 或者咱們即將提到的toString
方法進行判斷
Array.isArray(arrB) // true
toString
是Object.prototype
上的一個方法, 經常使用方式爲 Object.prototype.toString.call(target)
返回值是 [object 類型]
字符串,該方法基本上能判斷全部的數據類型(自定義數據類型除外)
// 定義判斷類型函數
let getType = target => Object.prototype.toString.call(target)
console.log(getType('')); // [object String]
console.log(getType(2)); // [object Number]
console.log(getType(true)); // [object Boolean]
console.log(getType(undefined)); // [object Undefined]
console.log(getType(null)); // [object Null]
console.log(getType(Symbol())); // [object Symbol]
console.log(getType({})); // [object Object]
console.log(getType([])); // [object Array]
console.log(getType(alert)); // [object Function]
console.log(getType(new RegExp())); // [object RegExp]
console.log(getType(new Date())); // [object Date]
複製代碼
該方法準確穩定,推薦使用
以上爲類型判斷的一些看法, 有不當之處, 還請大佬們指正!
相關知識點文章請參考: