手把手帶你寫一個JavaScript類型判斷小工具

      業務寫了不少,依然不是前端大神,我相信這是不少‘入坑’前端開發同窗的迷茫之處,我的以爲前端職業發展是有路徑可尋的,前期寫業務是一個積累過程,後期提煉總結,好比編程思想,父子類的原型繼承,仍是對象之間的關聯委託,設計模式的熟悉和運用,這都是一個前端工程師成長爲高級工程師的必經之路,而這條道路是須要咱們耐住性子,請相信,生活遲早會回報咱們的努力。

      話很少說,進入咱們今天的主題,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}複製代碼

但願對你有所幫助,這條路還很長,慢慢來~~~

後續敬請期待算法與數據結構系列~~~~

若是你以爲對你又幫你,請點個贊,這是對原創者最大的寫做分享動力~~~~

相關文章
相關標籤/搜索