[探索]怎麼樣的參數能讓 JS - API 更靈活

外在決定是否須要瞭解內在,內在決定是否會一票否決外在。內外結合,好上加好。

1.前言

開發 API 的時候,把參數的名字和位置肯定下來,函數定義就能夠說是完成了。由於 API 使用者來講,只須要知道如何傳遞參數,以及函數將返回什麼樣的值就夠了,無需瞭解內部。因此參數多多少少影響了 API 的一個靈活程度和使用複雜程度。在設計 API 的時候,應該怎麼設計參數,下面就簡單的寫下,若是你們有不一樣的想法,歡迎在評論區留言。javascript

下面使用的例子,除了原生了 JQuery 的 API。其餘的例子都是取自本身封裝的一個經常使用函數庫 ecDo 。歡迎提建議和 star。

2.何時該設置參數

其實何時設置參數並沒什麼什麼說法,規範。只要以爲用參數會使得 API 的使用會更加的簡單和靈活就用了。html

設置參數,可能一開始不會有很好的靈感,可是在使用過程當中,用得難受了,天然會像辦法優化。

好比 有 ecDo.count(array|string,item) 這個 API 就是統計一個數組的每一個元素的出現次數或者字符串每個字符的個數。java

這很容易實現,代碼也貼下jquery

count(arr) {
    let obj = {}, k, arr1 = []
    //記錄每一元素出現的次數
    for (let i = 0, len = arr.length; i < len; i++) {
        k = arr[i];
        if (obj[k]) {
            obj[k]++;
        } else {
            obj[k] = 1;
        }
    }
    //保存結果{el-'元素',count-出現次數}
    for (let o in obj) {
        arr1.push({el: o, count: obj[o]});
    }
    return arr1;
},



let strTest1='abbccc'
console.log(ecDo.count(strTest1));
//result:[{el: "a", count: 1},{el: "b", count: 2},el: "c", count: 3}]

可是有些時候,開發者並不須要知道全部元素的個數,好比就須要知道 'a' 的出現次數,這個狀況直接返回 'a' 的個數就好了,不須要像上面例子同樣,返回一個數組。這樣用起來會舒服一些,改起來也很簡單,只要增長一個參數,一個判斷便可。git

count(arr,item) {
    //重複代碼略
    return item?obj[item]:arr1;
},



let strTest1='abbccc'
console.log(ecDo.count(strTest1),'a');
//result:1

還有一個經常使用的 API 是ecDo.clearKeys(obj)--清除對象中值爲‘空’(null, undefined和'')的屬性。github

這個也很容易實現,ajax

clearKeys(obj) {
    let _newPar = {};
    for (let key in obj) {
        if (obj[key]===0||obj[key]===false||obj[key]) {
            _newPar[key] = obj[key];
        }
    }
    return _newPar;
},


ecDo.clearKeys({1:0,2:2,3:''})
//result:{1: 0, 2: 2}

想必你們也發現這樣寫法太不靈活了,若是下次要把 0false 的屬性也清空呢?若是下次要把值爲 '--' 的屬性也清空呢?這樣就作不到了,因此還要改一下,增長一個參數 clearValues - 待清空的值。數組

要使用的一個函數微信

clearKeys(obj, clearValues = [null, undefined, '']) {
    clearValues.forEach((item, index) => {
        clearValues[index] = Number.isNaN(item) ? 'NaN' : item
    });
    let _newPar = {};
    for (let key in obj) {
        //checkValue 看下面定義
        if (!checkValue(obj[key], clearValues)) {
            _newPar[key] = obj[key];
        }
    }
    return _newPar;
},


ecDo.clearKeys({a:'',b:0,c:11})
//result:{b: 0,c: 11}
ecDo.clearKeys({a:'',b:0,c:'--'},['--',''])
//result:{b: 0}
ecDo.clearKeys({a:'',b:0,c:11,d:false},[0,''])
//result:{c: 11,d: false}
ecDo.clearKeys({a:NaN,b:2,c:undefined},[NaN,undefined])
//result:{b: 2}

checkValue 函數cookie

function checkValue(val, vals) {
    let _val = val;
    if (Number.isNaN(val)) {
        _val = 'NaN'
    }
    return vals.indexOf(_val) !== -1;
}

這樣以來,想清除任何值的屬性,這裏均可以實現。

3.參數數量和前置

這兩個注意點能夠說是日常接觸最頻繁的,也是最無可辯解的。

首先參數的數量,在不影響 API 使用的狀況下確定是能少就少,越少越好。由於參數的越少,API 的記憶成本越低,調用也更加便利。

參數能少就少,越少越好,是有前提的--不影響 API 的使用。若是多個參數, API 使用能更方便,靈活,簡單。多個參數就多個參。

而後參數的前置性,就是參數相關性越高,越不能省略的,就越要放在前面。雖然能夠把可省略參數放後面,可是這樣問題可能會不少。

4.使用對象做爲參數

何時該使用對象做爲函數的參數,暫時發現是兩種狀況。

1.參數過多的時候

2.參數不固定的時候

好比 ajax 的參數,至少至少也有 5 個。url-請求連接,method-請求方式,data-請求參數,success-成功回調,fail-失敗回調。若是不使用對象做爲參數,完整的寫法,是下面這樣

ajax(url,method,data,success,fail)

但這5個參數裏面,除了 url ,其餘參數均可以省略或者默認。若是隻須要傳 url 和 success,須要像下面這樣寫

ajax(url,'','',success)

由於參數的順序不能亂,因此就要這樣寫。這樣多難受就不說了,若是參數過多,參數看着會很長,容易搞錯參數順序,就會出現問題了。

若是使用對象傳參,就舒服不少了。

ajax({url:url,success:function(){}})

這樣寫的會多一點,可是好處也有。首先用戶仍是須要記住參數名,但不用關心參數順序,不用擔憂參數過多。而後就是開發者想增長多少參數都比較方便,也不用關心參數後置的問題。

是否使用對象做爲參數,判斷的指標應該只有一個:是否方便使用,靈活。

5.參數默認值

何時應該設計默認值?也分幾種狀況討論

首先是,一個參數值出現頻率比其餘狀況大的時候。好比有一個 ecDo.encrypt(str,regIndex,repText) 的 API,做用很簡單,就是對字符串的特定位置進行加密。好比常常會遇到隱藏用戶的手機號碼的需求。

電話號碼隨便編造的
ecDo.encrypt('18819233362','3,7')
//result:188*****362

ecDo.encrypt('18819233362','3,7','+')
//result:188+++++362

ecDo.encrypt('18819233362','4')
//result:*****233362

ecDo.encrypt('18819233362','-4')
//result:188192*****

在這個 API 裏面 ,第三個參數 repText 可能大多數狀況都是使用 。若是不對 repText 設置默認值,若是每一次都傳一個 ,不但寫的多,看得也難受。

還有一種狀況,從特定位置執行到結尾結束的時候。好比原生的 substr(start,length) ,第一個參數是開始字符的下標,第二個參數是截取的長度。若是省略,就從開始位置截取到結尾。這樣就算是一種方便。

5.參數多態

這裏說的參數多態跟繼承方面的多態有點區別

參數多態這個很常見,目的很簡單,就是經過不一樣的傳參方式讓一個函數進行不一樣的操做。看到這裏,可能你們一會兒就想到 splice。由於一個 splice 能夠實現數組的增長,刪除,替換

//刪除
let arr=[1,2,3,4,5,6]
arr.splice(0,1)
//result:arr:[2, 3, 4, 5, 6]

//替換
arr=[1,2,3,4,5,6]
arr.splice(2,1,0)
//result:arr:[1, 2, 0, 4, 5, 6]

//增長
arr=[1,2,3,4,5,6]
arr.splice(2,0,0)
//result:arr:[1, 2, 0, 3, 4, 5, 6]

可是 splice 應該並不算是參數多態,只能算是一些技巧的一個寫法。

表現出參數多態的,好比 JQuery 的 attr 。既能夠獲取屬性的值,也能夠設置屬性的值。

//獲取 dom 元素 id 的值
$(dom).attr('id')
//設置 dom 元素 id 的值
$(dom).attr('id','domId')

JQuery 把多態表現得更好的應該是 $() 。JQuery 火的緣由,跟這個 $() 有很大的關係,只要是合法的選擇器,頁面存在這個元素,就能找到。讓選擇元素變得很是簡單。

關於 $() 的強大特性,可參考 jQuery 選擇器

在本身封裝 API 的時候,也會遇到操做 cookie 的一系列操做(設置,獲取,刪除)。以前是這樣

ecDo.setCookie(cookieName,value,day)//設置(cookie名稱,cookie值,有效的天數)
ecDo.getCookie(cookieName)//獲取
ecDo.removeCookie(cookieName)//刪除

如今是這樣

ecDo.cookie(cookieName,value,day)//設置(cookie名稱,cookie值,有效的天數)
ecDo.cookie(cookieName)//獲取
ecDo.cookie(cookieName,value,-1)//刪除

這樣使用起來,就比以前簡單一點,至關於只是記住一個 API 就能夠了。

參數的多態,就是讓 API 的指責會根據參數的狀況進行改變。至關於把類似職責的 API 給合併成一個。不須要給用戶提供出太多 API,方便用戶的使用。即便這樣可能違法了單一指責原則,可是呼應了最少知識原則。能讓 API 的使用盡量簡單化了。

5-1.何時不應設置參數多態

參數多態就是把類似職責的 API 給合併成一個。可是有時候並不適合使用。更適合把合併的 API 拆分紅幾個。

好比以前封裝經常使用 API 的時候。有一個去除字符串空格的 API : ecDo.trim(str,type) (str-待處理的字符串,type-去除空格的類型----1-左右空格,2-全部空格,3-左空格,4-右空格) 。

使用形式

ecDo 是我封裝的一個經常使用函數庫。
let str=' 守 候 ';
console.log(ecDo.trim(str,1));//'守 候'
console.log(ecDo.trim(str,2));//'守候'
console.log(ecDo.trim(str,3));//'守候 '
console.log(ecDo.trim(str,4));//' 守候'

這樣使用的話,想必你們都看到問題了。1 2 3 4 是什麼鬼?就算知道是什麼鬼,也要把這幾個鬼記住。記憶成本大,調用也不方便。後來就拆分紅四個函數了。

let str=' 守 候 ';
console.log(ecDo.trim(str));//'守 候'
console.log(ecDo.trimAll(str));//'守候'
console.log(ecDo.trimLeft(str));//'守候 '
console.log(ecDo.trimRright(str));//' 守候'

這樣雖然多了幾個 API 可是使用起來簡單了。記憶成本也比以前少。是否設置參數多態,仍是要看調用的狀況而言。

6.小結

好了,關於 API 參數方面的東西就暫時寫到這裏了,這部分的內容很少,因此篇幅不是很長,也容易理解。可是參數這個話題也相對開放,若是你們有什麼好的想法。歡迎在評論區留言。

-------------------------華麗的分割線--------------------

想了解更多,和我交流,內推職位,請添加我微信。或者關注個人微信公衆號:守候書閣

圖片描述圖片描述

相關文章
相關標籤/搜索