話很少說,進入咱們今天的主題,JavaScript中判斷一個數據的類型有多種方式:typeof、instanceof、constructor、Object.prototype.toString.call,通常判斷簡單的數據類型咱們會使用typeof,可是對於數組,正則類型的數據,typeof是無能爲力的,instanceof通常用於判斷對象的繼承關係,今天咱們主要說的是Object.prototype.toString.call這個方法。前端
1.判斷類型 程序員
咱們能夠寫一個isType的方法來判斷數據的類型,傳入兩個參數,第一個是須要判斷的數據,第二個是數據類型。算法
前置知識:各個類型經過Object.prototype.toString.call方法後獲得的結果
console.log(Object.prototype.toString.call('hello')) //[object String]
console.log(Object.prototype.toString.call(34)) //[object Number]
console.log(Object.prototype.toString.call(true))// [object Boolean]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(function f() {})) // [object Function]
下面咱們就開始擼代碼了:
function isType(content,type){
//這裏咱們經過正則匹配去掉'[object ]',只留下類型
let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
//將獲得的t與傳入的type進行比較,返回結果,結果爲Boolean類型
return t === type;
}
//執行函數並將結果返回給res,打印res
let res = isType('hello','String')
console.log(res);//true複製代碼
是否是很是簡單,對本身又充滿信心了,不過如此嘛!!確實很簡單,來,繼續,一點點深刻~~npm
經過上面的一個函數咱們就能夠很容易的判斷一個JavaScript數據的類型,可是咱們在使用的時候是這個樣子的:編程
let res1 = isType('hello','String');
let res2 = isType(123,'Number');
let res3 = isType(true,'Boolean');
複製代碼
咱們每次在使用的時候都是手動傳入類型,頗有可能手一抖,就傳錯類型了,原本'String',咱們傳入了'Strings',是否是很坑爹呀~~設計模式
通常的庫或者插件不會這樣去讓咱們使用,通常會這麼使用utils.isString('hello'),咱們只須要傳入咱們的數據就能夠了,插件會提供相應的判斷方法,好比數組
utils.isString('hello');
utils.isNumber(123);
utils.isBoolean(true);複製代碼
這裏咱們須要批量化生產函數,就須要用到下面的一個函數返回一個函數,也就是所謂的閉包,也被叫作高階函數,不要那些高大上,咱們程序員都是接地氣的~~,初學者對於閉包理解起來比較困難,不着急,隨着你的深刻,都會明白的~~~bash
2.一個函數返回一個函數前端工程師
接下來咱們對上面的isType函數進行改造,數據結構
let isNumber = isType('Number');
let isString = isType('String');
let isBoolean = isType('Boolean');
isNumber(12);
isString('hello');
isBoolean(true)複製代碼
經過執行isType(),咱們能夠獲得想要的函數,說明在isType內部,我麼返回了一個函數,返回的這個函數對於外層函數 (也就是isType) 的參數進行了引用,JavaScript的垃圾回收機制是不會回收被引用的數據的,因此type被保留在了返回函數的內部,這就是閉包機制。
function isType(type) {
return function(content) {
let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
return t === type;
}
}複製代碼
經過執行isType,咱們獲得了對內部函數的引用。
isNumber(12);
isString('hello');
isBoolean(true);複製代碼
上面其實就是對isType內部函數的執行。
也不過如此嘛,說好的手把手帶咱們寫一個判斷類型插件呢!?
3.屬於咱們本身的判斷JavaScript類型插件
有些同窗已經有啓發了,咱們能夠這樣操做
let type = ['String','Number','Function','Undefined','Boolean','Array'];
let utils = {};
type.forEach(item => {
utils['is' + item] = isType(item);
})
複製代碼
下面是console.log(utils)的結果
是否是很驚喜~~
咱們能夠利用ES6的模塊化機制來封裝這個方法,而後erport 出去供小夥伴使用,是否是很簡單,也能夠上傳到npm,供廣大開發者使用,是否是頗有成就感。(估計這個難度的插件去你npm下載使用的人幾乎沒有,這裏咱們掌握怎麼經過閉包去處理問題這個思想就行)下面是完整版utils.js
function isType(type) {
return function(content) {
let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
return t === type;
}
}
function createUtils(){
let utils = {};
let type = ['String','Number','Function','Undefined','Boolean','Array'];
type.forEach(item => {
utils['is' + item] = isType(item);
})
return utils;
}
let utils = createUtils();
export default{utils}複製代碼
但願對你有所幫助,這條路還很長,慢慢來~~~
後續敬請期待算法與數據結構系列~~~~
若是你以爲對你又幫你,請點個贊,這是對原創者最大的寫做分享動力~~~~