有没有办法允许JavaScript中的函数使用“无限”的var?
例:
load(var1, var2, var3, var4, var5, etc...)
load(var1)
#1楼
我同意Ken的回答是最有活力的,并且我想更进一步。 如果您使用不同的参数多次调用该函数-我使用Ken的设计,然后添加默认值:
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
这样,如果您有许多参数,但不必每次调用该函数都进行设置,则只需指定非默认值即可。 对于extend方法,可以使用jQuery的extend方法( $.extend()
),自己$.extend()
或使用以下方法:
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
这将合并上下文对象和默认值,并使用默认值填充对象中所有未定义的值。
#2楼
尽管我通常都同意命名实参方法是有用且灵活的(除非您关心顺序,否则实参最简单),但我确实对mbeasley方法(使用默认值和扩展名)的成本感到担忧。 拉取默认值要花费极高的成本。 首先,默认值是在函数内部定义的,因此每次调用都会重新填充它们。 其次,您可以轻松地读出命名值并使用||同时设置默认值。 无需创建和合并另一个新对象即可获取此信息。
function load(context) {
var parameter1 = context.parameter1 || defaultValue1,
parameter2 = context.parameter2 || defaultValue2;
// do stuff
}
这大约是相同数量的代码(可能略多),但是应该只是运行时成本的一小部分。
#3楼
当然,只需使用arguments
对象。
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
#4楼
在arguments
内部使用arguments
对象可以访问所有传入的参数。
#5楼
是的,就像这样:
function load()
{
var var0 = arguments[0];
var var1 = arguments[1];
}
load(1,2);
#6楼
另一种选择是在上下文对象中传递参数。
function load(context)
{
// do whatever with context.name, context.address, etc
}
像这样使用
load({name:'Ken',address:'secret',unused:true})
这样做的好处是,您可以根据需要添加任意数量的命名参数,并且函数可以根据需要使用(或不使用)它们。
#7楼
请注意,按照Ken的建议传递带有命名属性的Object会增加分配和释放临时对象到每个调用的成本。 通过值或引用传递普通参数通常是最有效的。 对于许多应用程序而言,性能并不关键,但对于某些应用程序则可能至关重要。
#8楼
如前所述,您可以使用arguments
对象检索可变数量的函数参数。
如果要使用相同的参数调用另一个函数,请使用apply
。 您甚至可以通过将arguments
转换为数组来添加或删除参数。 例如,此函数在登录到控制台之前插入一些文本:
log() {
let args = Array.prototype.slice.call(arguments);
args = ['MyObjectName', this.id_].concat(args);
console.log.apply(console, args);
}
#9楼
在(大多数)最新的浏览器中,您可以使用以下语法接受数量可变的参数:
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
这是一个小例子:
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
文档和更多示例在这里: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
#10楼
如Ramast所指出的,最好使用rest参数语法。
function (a, b, ...args) {}
我只想添加... args参数的一些不错的属性
- 它是一个数组,而不是类似参数的对象。 这使您可以应用地图或直接排序等功能。
- 它不包括所有参数,而仅包括从其传递过来的参数。 例如,在这种情况下,函数(a,b,... args)args包含arguments.length的参数3
#11楼
虽然@roufamatic确实显示了arguments关键字的使用,而@Ken显示了使用对象的一个很好的例子,但我觉得既没有真正解决这种情况下发生的情况,也可能使未来的读者感到困惑或因为未明确说明功能而引起不良做法/ method旨在采用可变数量的参数/参数。
function varyArg () {
return arguments[0] + arguments[1];
}
当另一个开发人员浏览您的代码时,很容易假设此函数不带参数。 尤其是如果该开发人员不擅长使用arguments关键字。 因此,遵循样式指南并保持一致是一个好主意。 我将在所有示例中使用Google的。
让我们明确声明相同的函数具有可变参数:
function varyArg (var_args) {
return arguments[0] + arguments[1];
}
对象参数VS var_args
有时可能需要一个对象,因为它是数据映射表中唯一被批准并认为是最佳实践的方法。 联想数组不赞成使用,不鼓励使用。
旁白: arguments关键字实际上使用数字作为键返回一个对象。 原型继承也是对象家族。 请参阅答案结尾以了解JS中正确的数组用法
在这种情况下,我们也可以明确声明这一点。 注意:此命名约定不是Google提供的,而是一个显式声明参数类型的示例。 如果要在代码中创建更严格的类型化模式,这一点很重要。
function varyArg (args_obj) {
return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});
选择哪一个?
这取决于您的功能和程序的需求。 例如,如果您只是想在所有传递的参数上基于迭代过程返回一个值,那么肯定可以使用arguments关键字。 如果您需要定义参数和数据映射,那么对象方法就是您的理想之选。 让我们看两个示例,然后完成!
参数用法
function sumOfAll (var_args) {
return arguments.reduce(function(a, b) {
return a + b;
}, 0);
}
sumOfAll(1,2,3); // returns 6
对象使用
function myObjArgs(args_obj) {
// MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
if (typeof args_obj !== "object") {
return "Arguments passed must be in object form!";
}
return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old
访问数组而不是对象(“ ... args” rest参数)
如答案顶部所述, arguments关键字实际上返回一个对象。 因此,必须调用要用于数组的任何方法。 一个例子:
Array.prototype.map.call(arguments, function (val, idx, arr) {});
为了避免这种情况,请使用rest参数:
function varyArgArr (...var_args) {
return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5