不定参数
怎样完成不定参数
运用过 underscore.js 的人,一定都运用过以下几个要领:
_.without(array, *values) //返回一个删除一切values值后的array副本
_.union(*arrays) //返回传入的arrays(数组)并集
_.difference(array, *others)//返回来自array参数数组,而且不存在于other 数组
...
这些要领都有一个共同点,就是能够传入不定数目的参数,比如,我想删撤除 array
中的 value1,value2
,能够如许运用 , _.without(array,value1,value2);
那末,这个须要怎样才能做到呢?
我们晓得,js 中 function
内里,有一个 arguments
参数,它是一个类数组,内里包含着挪用这个要领的一切参数,所以能够如许处置惩罚:
_.without = function() {
if (arguments.length > 0) {
var array = arguments[0];
var values = [];
for (var i = 1; i < arguments.length; i++) {
values.push(arguments[i]);
}
//如许得到了array,和values数组,便能够进一步处置惩罚了
}
};
上面只是打个比如,想要支撑不定参数,我们要做的就是把牢固参数和动态参数从 arguments 中分离出来。
然则,我们如许写的话,须要在每一个支撑不定参数的函数里,都 copy 如许一段代码,如许着实不是很文雅。所以须要封装成一个通用的函数。
我们直接看看 underscore 是封装的好了。
restArgs 源码
var restArgs = function(func, startIndex) {
//startIndex ,示意几个参数以后就是动态参数
startIndex = startIndex == null ? func.length - 1 : +startIndex;
return function() {
var length = Math.max(arguments.length - startIndex, 0);
//处置惩罚arguments,将动态参数保留进rest数组
var rest = Array(length);
for (var index = 0; index < length; index++) {
rest[index] = arguments[index + startIndex];
}
//处置惩罚0,1,2三种状况,这里要零丁处置惩罚,是想优先运用call,由于,call的性能比apply要好一点
switch (startIndex) {
case 0:
return func.call(this, rest);
case 1:
return func.call(this, arguments[0], rest);
case 2:
return func.call(this, arguments[0], arguments[1], rest);
}
//假如startIndex不是0,1,2三种状况,则运用apply挪用要领,将args作为参数,args将为数组[牢固参数 ,rest];
var args = Array(startIndex + 1);
for (index = 0; index < startIndex; index++) {
args[index] = arguments[index];
}
args[startIndex] = rest;
return func.apply(this, args);
};
};
//这里without重要的逻辑处置惩罚要领,作为参数,传给restArgs,在restArgs中处置惩罚完参数后,运用call或apply挪用逻辑处置惩罚要领
// 这时候接受到参数otherArrays,已经是一个数组了,包含了之前的动态参数。
_.without = restArgs(function(array, otherArrays) {
//处置惩罚without详细事宜
});
underscore.js 中应用 js 高等函数的特征,奇妙的完成了动态参数
假如要使某函数支撑不定参数,只须要将该函数作为参数,传入 restArgs 中即可,比如:
function addByArray(values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
sum += values[i];
}
return sum;
}
var add = restArgs(addByArray);
//挪用:
addByArray([2, 5, 3, 6]); //16
add(2, 5, 3, 6); //16
ES6 不定参数 (…)
ES6 引入了 rest 参数,(情势为”…变量名”),用于猎取过剩参数,如许就不须要运用 arguments 对象来完成了
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3); // 10
总结
在 underscore 中,restArgs 只是为了支撑不定参数。实际运用中,或许我们都是直接运用 ES6,或用 babel 将 ES6 转成 ES5 来支撑不定参数
不过,假如是在非 es6 的环境下,晓得有这么一种完成体式格局,也是挺好的。
:)