話不多說,進入我們今天的主題,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複製程式碼
是不是非常簡單,對自己又充滿信心了,不過如此嘛!!確實很簡單,來,繼續,一點點深入~~
通過上面的一個函式我們就可以很容易的判斷一個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);複製程式碼
這裡我們需要批量化生產函式,就需要用到下面的一個函式返回一個函式,也就是所謂的閉包,也被叫做高階函式,不要那些高大上,我們程式設計師都是接地氣的~~,初學者對於閉包理解起來比較困難,不著急,隨著你的深入,都會明白的~~~
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}複製程式碼
希望對你有所幫助,這條路還很長,慢慢來~~~
後續敬請期待演算法與資料結構系列~~~~
如果你覺得對你又幫你,請點個贊,這是對原創者最大的寫作分享動力~~~~