指示某个功能使用'参数'的最佳方式是什么?反对呢?
这显然是基于意见的,但有没有任何约定?什么时候使用一组参数会更好?
一些例子:
// Function takes n arguments and makes them pretty.
function manyArgs() {
for (var i = 0; i < arguments.length; i++)
console.log(arguments[i]);
}
function manyArgs( /* n1 , n2, ... */ )
function manyArgs(n1 /*, n2, ... */ )
function manyArgs(argArray)
答案 0 :(得分:4)
我从不在JavaScript中使用可变参数。有许多更好的方法来构建代码。例如,我会按如下方式重写您的代码:
[1,2,3,4,5].forEach(log); // instead of manyArgs(1,2,3,4,5);
function log(a) {
console.log(a);
}
它清晰简洁。
另一个例子,如果你想在JavaScript中找到一个数字列表的总和:
[1,2,3,4,5].reduce(add, 0); // instead of add(1,2,3,4,5);
function add(a, b) {
return a + b;
}
有很多有用的抽象可用于构造代码,我根本没有看到使用可变参数的好处。
但我使用arguments
对象作为默认值:
function foo(a,b,c) {
switch (arguments.length) {
case 0: a = "default argument for a";
case 1: b = "default argument for b";
case 2: c = "default argument for c";
}
// do something with a, b & c
}
因此我建议你不要使用可变参数。为代码找到更好的抽象。我在用JavaScript编程的8年里从未遇到过使用可变参数的需要。
编辑:我主张使用更实用的方法来编写代码。我们可以使用currying使代码更简洁:
function curry(func, length, args) {
switch (arguments.length) {
case 1: length = func.length;
case 2: args = [];
}
var slice = args.slice;
return function () {
var len = arguments.length;
var a = args.concat(slice.call(arguments));
if (len >= length) return func.apply(this, a);
return curry(func, length - len, a);
};
}
使用curry
我们可以按如下方式重写sum示例:
var reduce = curry(function (func, acc, a) {
var index = 0, length = a.length;
while (index < length) acc = func(acc, a[index++]);
return acc;
});
var sum = reduce(add, 0);
sum([1,2,3,4,5]); // instead of add(1,2,3,4,5);
function add(a, b) {
return a + b;
}
同样适用于Math.max
和Array.prototype.concat
:
var reduce1 = curry(function (func, a) {
if (a.length === 0)
throw new Error("Reducing empty array.");
return reduce(func, a[0], a.slice(1));
});
var maximum = reduce1(max);
maximum([1,2,3,4,5]); // instead of Math.max(1,2,3,4,5);
function max(a, b) {
return a > b ? a : b;
}
var concat = reduce(function (a, b) {
return a.concat(b);
}, []);
concat([[1,2],[3,4],[5,6]]) // instead of [1,2].concat([3,4],[5,6])
对于Array.prototype.push
,因为它改变了输入数组而不是创建新数组,所以我更喜欢使用array.concat([element])
而不是array.push(element)
:
var push = reduce(function (a, e) {
return a.concat([e]);
});
push([1,2,3], [4,5]); // instead of [1,2,3].push(4, 5)
那么以这种方式编写代码有什么好处:
arguments
。array
的数组的总和。使用此方法,您只需执行sum(array)
。如果使用可变参数,则需要执行add.apply(null, array)
。a
,b
&amp;的总和。 c
。与sum([a,b,c])
相比,您需要做的只是add(a, b, c)
。您需要输入额外的[]
括号。但这样做会使您的代码更容易理解。根据{{3}} “显式优于隐式”。所以这些是我从未在我的程序中使用可变参数的一些原因。
答案 1 :(得分:0)
// Using ES6 syntax ...
var foo = function(/*...args*/){
// shim Array.from, then
var args = Array.from(arguments);
// or
var args = [].slice.call(arguments);
};
答案 2 :(得分:0)
最明确的方法是使用ES6,CoffeeScript中可用的点差运算符(它们被称为&#34; splats&#34;三个点位于标识符之后),{ {3}}(称为&#34;休息参数&#34;)。
// Function takes n arguments and makes them pretty.
function manyArgs(...args) {
for (var i = 0; i < args.length; i++)
console.log(args[i]);
}
当然,如果您处于可以使用它们的环境中。它既可以更好地自我记录,又可以避免不得不使用arguments
。