是否可以向 JavaScript 函数发送可变数量的参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1959040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to send a variable number of arguments to a JavaScript function?
提问by Fire Crow
Is it possible to send a variable number of arguments to a JavaScript function, from an array?
是否可以从数组向 JavaScript 函数发送可变数量的参数?
var arr = ['a','b','c']
var func = function()
{
// debug
alert(arguments.length);
//
for(arg in arguments)
alert(arg);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
I've recently written a lot of Python and it's a wonderful pattern to be able to accept varargs and send them. e.g.
我最近写了很多 Python,能够接受可变参数并发送它们是一个很棒的模式。例如
def func(*args):
print len(args)
for i in args:
print i
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'
Is it possible in JavaScript to send an array to be treated asthe arguments array?
在 JavaScript 中是否可以发送一个数组作为参数数组?
回答by CMS
Update: Since ES6, you can simply use the spread syntaxwhen calling the function:
更新:从 ES6 开始,您可以在调用函数时简单地使用spread 语法:
func(...arr);
Since ES6 also if you expect to treat your arguments as an array, you can also use the spread syntax in the parameter list, for example:
由于 ES6 同样,如果您希望将参数视为数组,您还可以在参数列表中使用 spread 语法,例如:
function func(...args) {
args.forEach(arg => console.log(arg))
}
const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)
And you can combine it with normal parameters, for example if you want to receive the first two arguments separately and the rest as an array:
并且您可以将它与普通参数结合使用,例如,如果您想分别接收前两个参数并将其余参数作为数组接收:
function func(first, second, ...theRest) {
//...
}
And maybe is useful to you, that you can know how many arguments a function expects:
也许对你有用,你可以知道一个函数需要多少个参数:
var test = function (one, two, three) {};
test.length == 3;
But anyway you can pass an arbitrary number of arguments...
但无论如何你可以传递任意数量的参数......
The spread syntax is shorter and "sweeter" than applyand if you don't need to set the thisvalue in the function call, this is the way to go.
传播语法比apply如果您不需要this在函数调用中设置值更短更“甜蜜” ,这就是要走的路。
Here is an applyexample, which was the former way to do it:
这是一个应用示例,这是以前的方法:
var arr = ['a','b','c'];
function func() {
console.log(this); // 'test'
console.log(arguments.length); // 3
for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
};
func.apply('test', arr);
Nowadays I only recommend using applyonly if you need to pass an arbitrary number of arguments from an array andset the thisvalue. applytakes is the thisvalue as the first arguments, which will be used on the function invocation, if we use nullin non-strict code, the thiskeyword will refer to the Global object (window) inside func, in strict mode, when explicitly using 'use strict' or in ES modules, nullwill be used.
现在,我只建议apply仅在需要从数组中传递任意数量的参数并设置this值时才使用。applytake 是this作为第一个参数的值,将在函数调用时使用,如果我们null在非严格代码中使用,则this关键字将引用内部的全局对象(窗口)func,在严格模式下,当显式使用 'use strict ' 或在 ES 模块中,null将被使用。
Also note that the argumentsobject is not really an Array, you can convert it by:
另请注意,该arguments对象并不是真正的数组,您可以通过以下方式对其进行转换:
var argsArray = Array.prototype.slice.call(arguments);
And in ES6:
在 ES6 中:
const argsArray = [...arguments] // or Array.from(arguments)
But you rarely use the argumentsobject directly nowadays thanks to the spread syntax.
但是arguments由于扩展语法,您现在很少直接使用该对象。
回答by danben
You can actually pass as many values as you want to any javascript function. The explicitly named parameters will get the first few values, but ALL parameters will be stored in the arguments array.
您实际上可以将任意数量的值传递给任何 javascript 函数。显式命名的参数将获得前几个值,但所有参数都将存储在参数数组中。
To pass the arguments array in "unpacked" form, you can use apply, like so (c.f. Functional Javascript):
要以“解压缩”形式传递参数数组,您可以使用 apply,如下所示(参见Functional Javascript):
var otherFunc = function() {
alert(arguments.length); // Outputs: 10
}
var myFunc = function() {
alert(arguments.length); // Outputs: 10
otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
回答by Tgr
The splatand spreadoperators are part of ES6, the planned next version of Javascript. So far only Firefox supports them. This code works in FF16+:
该图示和传播运营商ES6,使用Javascript的计划下一个版本的一部分。到目前为止,只有 Firefox 支持它们。此代码适用于 FF16+:
var arr = ['quick', 'brown', 'lazy'];
var sprintf = function(str, ...args)
{
for (arg of args) {
str = str.replace(/%s/, arg);
}
return str;
}
sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');
Note the awkard syntax for spread. The usual syntax of sprintf('The %s %s fox jumps over the %s dog.', ...arr);is not yet supported. You can find an ES6 compatibility table here.
请注意传播的尴尬语法。通常的语法sprintf('The %s %s fox jumps over the %s dog.', ...arr);是不被支持。您可以在此处找到ES6 兼容性表。
Note also the use of for...of, another ES6 addition. Using for...infor arrays is a bad idea.
回答by Braden Best
There are two methods as of ES2015.
ES2015 有两种方法。
The argumentsObject
该arguments对象
This object is built into functions, and it refers to, appropriately, the arguments of a function. It is not technically an array, though, so typical array operations won't work on it. The suggested method is to use Array.fromor the spread operator to create an array from it.
该对象内置于函数中,它适当地引用了函数的参数。不过,从技术上讲,它不是数组,因此典型的数组操作不适用于它。建议的方法是使用Array.from或 展开运算符从它创建一个数组。
I've seen other answers mention using slice. Don't do that. It prevents optimizations (source: MDN).
我已经看到其他答案提到使用slice. 不要那样做。它会阻止优化(来源:MDN)。
Array.from(arguments)
[...arguments]
However, I would argue that argumentsis problematic because it hides what a function accepts as input. An argumentsfunction typically is written like this:
但是,我认为这arguments是有问题的,因为它隐藏了函数接受的输入。一个arguments函数通常是这样写的:
function mean(){
let args = [...arguments];
return args.reduce((a,b)=>a+b) / args.length;
}
Sometimes, the function header is written like the following to document the arguments in a C-like fashion:
有时,函数头的编写方式如下,以类似 C 的方式记录参数:
function mean(/* ... */){ ... }
But that is rare.
但这很少见。
As for why it is problematic, take C, for example. C is backwards compatible with an ancient pre-ANSI dialect of the language known as K&R C. K&R C allows function prototypes to have an empty arguments list.
至于为什么会出问题,就拿C来说吧。C 向后兼容 K&R C 语言的一种古老的 pre-ANSI 方言。 K&R C 允许函数原型具有空参数列表。
int myFunction();
/* This function accepts unspecified parameters */
ANSI C provides a facility for varargs(...), and voidto specify an empty arguments-list.
ANSI C 为varargs( ...)提供了一个工具,并void指定一个空的参数列表。
int myFunction(void);
/* This function accepts no parameters */
Many people inadvertently declare functions with an unspecifiedarguments list (int myfunction();), when they expect the function to take zero arguments. This is technically a bug because the function willaccept arguments. Any number of them.
许多人不经意地用unspecified参数列表 ( int myfunction();)声明函数,因为他们希望函数采用零个参数。这在技术上是一个错误,因为该函数将接受参数。任意数量。
A proper varargsfunction in C takes the form:
C 中的适当varargs函数采用以下形式:
int myFunction(int nargs, ...);
And JavaScript actually does have something similar to this.
JavaScript 确实有类似的东西。
Spread Operator/ Rest Parameters
扩展运算符/其余参数
I've already shown you the spread operator, actually.
实际上,我已经向您展示了价差运算符。
...name
It's pretty versatile, and can also be used in a function's argument-list ("rest parameters") to specify varargs in a nicely documented fashion:
它非常通用,也可以用在函数的参数列表(“其余参数”)中,以记录良好的方式指定可变参数:
function mean(...args){
return args.reduce((a,b)=>a+b) / args.length;
}
Or as a lambda expression:
或者作为 lambda 表达式:
((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3
I much prefer the spread operator. It is clean and self-documenting.
我更喜欢传播运算符。它是干净的和自我记录的。
回答by August Lilleaas
The applyfunction takes two arguments; the object thiswill be binded to, and the arguments, represented with an array.
该apply函数有两个参数;对象this将被绑定到,参数用数组表示。
some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
回答by Chandra Patni
It's called the splatoperator. You can do it in JavaScript using apply:
它被称为splat操作员。你可以在 JavaScript 中使用apply:
var arr = ['a','b','c','d'];
var func = function() {
// debug
console.log(arguments.length);
console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr);
回答by theres.yer.problem
With ES6 you can use rest parametersfor varagrs. This takes the argument list and converts it to an array.
随着ES6您可以使用其他参数进行varagrs。这需要参数列表并将其转换为数组。
function logArgs(...args) {
console.log(args.length)
for(let arg of args) {
console.log(arg)
}
}
回答by yckart
(function(window) {
var proxied = window.alert;
window.alert = function() {
return proxied.apply(window, arguments);
};
}(this));
alert(13, 37);
回答by streak
This is a sample program for calculating sum of integers for variable arguments and array on integers. Hope this helps.
这是一个用于计算变量参数和整数数组的整数总和的示例程序。希望这可以帮助。
var CalculateSum = function(){
calculateSumService.apply( null, arguments );
}
var calculateSumService = function(){
var sum = 0;
if( arguments.length === 1){
var args = arguments[0];
for(var i = 0;i<args.length; i++){
sum += args[i];
}
}else{
for(var i = 0;i<arguments.length; i++){
sum += arguments[i];
}
}
alert(sum);
}
//Sample method call
// CalculateSum(10,20,30);
// CalculateSum([10,20,30,40,50]);
// CalculateSum(10,20);
回答by andrewtc
For those who were redirected here from Passing variable number of arguments from one function to another(which should notbe marked as a duplicate of this question):
对于那些谁是从重定向到这里传递的参数变量数量从一个功能到另一个(这应该不是被标记为这个问题的副本):
If you're trying to pass a variable number of arguments from one function to another, since JavaScript 1.8.5 you can simply call apply()on the second function and pass in the argumentsparameter:
如果您尝试将可变数量的参数从一个函数传递到另一个函数,从 JavaScript 1.8.5 开始,您可以简单地调用apply()第二个函数并传入arguments参数:
var caller = function()
{
callee.apply( null, arguments );
}
var callee = function()
{
alert( arguments.length );
}
caller( "Hello", "World!", 88 ); // Shows "3".
Note:The first argument is the thisparameter to use. Passing nullwill call the function from the global context, i.e. as a global function instead of the method of some object.
注意:第一个参数是this要使用的参数。传递null将从全局上下文中调用函数,即作为全局函数而不是某个对象的方法。
According to this document, the ECMAScript 5 specification redefined the apply()method to take any "generic array-like object", instead of strictly an Array. Thus, you can directly pass the argumentslist into the second function.
根据本文档,ECMAScript 5 规范重新定义了该apply()方法以采用任何“通用类数组对象”,而不是严格意义上的数组。因此,您可以直接将arguments列表传递给第二个函数。
Tested in Chrome 28.0, Safari 6.0.5, and IE 10. Try it out with this JSFiddle.
在 Chrome 28.0、Safari 6.0.5 和 IE 10 中测试。用这个 JSFiddle 试试。

