[探索]怎么样的参数能让 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 参数方面的东西就暂时写到这里了,这部分的内容很少,因此篇幅不是很长,也容易理解。可是参数这个话题也相对开放,若是你们有什么好的想法。欢迎在评论区留言。

-------------------------华丽的分割线--------------------

想了解更多,和我交流,内推职位,请添加我微信。或者关注个人微信公众号:守候书阁

图片描述图片描述

相关文章
相关标签/搜索