是否可以从数组向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'
我最近写了很多Python,这是一个很好的模式,能够接受varargs并发送它们。 e.g。
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'
在JavaScript中是否可以发送一个数组来处理作为 arguments数组?
答案 0 :(得分:170)
更新:从ES6开始,您可以在调用函数时使用spread syntax:
func(...arr);
由于ES6也希望将参数视为数组,因此您也可以在参数列表中使用扩展语法,例如:
function func(...args) {
args.forEach(arg => console.log(arg))
}
const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)
您可以将它与普通参数结合使用,例如,如果您想分别接收前两个参数而将其余参数作为数组:
function func(first, second, ...theRest) {
//...
}
也许对你有用,你可以知道函数需要多少个参数:
var test = function (one, two, three) {};
test.length == 3;
但无论如何你可以传递任意数量的参数......
扩展语法比apply
更短,更“甜蜜”,如果您不需要在函数调用中设置this
值,那么就可以了。
这是一个apply示例,这是以前的方法:
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);
现在我只推荐使用apply
,只要你需要从数组中传递任意数量的参数并设置this
值。 apply
take是this
值作为第一个参数,将在函数调用中使用,如果我们在非严格代码中使用null
,this
关键字将在严格模式下,参考func
内的全局对象(窗口),当明确使用'use strict'时,或者在ES模块中,将使用null
。
另请注意,arguments
对象实际上不是数组,您可以通过以下方式对其进行转换:
var argsArray = Array.prototype.slice.call(arguments);
在ES6中:
const argsArray = [...arguments] // or Array.from(arguments)
但是由于传播语法,你现在很少直接使用arguments
对象。
答案 1 :(得分:72)
您实际上可以将任意数量的值传递给任何javascript函数。显式命名的参数将获得前几个值,但所有参数都将存储在arguments数组中。
要以“解压缩”形式传递arguments数组,您可以使用apply,如此(c.f。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);
答案 2 :(得分:22)
splat和spread运算符是ES6的一部分,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');
请注意传播的awkard语法。 sprintf('The %s %s fox jumps over the %s dog.', ...arr);
的通常语法是not yet supported。您可以找到an ES6 compatibility table here。
另请注意使用另外的ES6 for...of
。对数组使用for...in
是a bad idea。
答案 3 :(得分:8)
ES2015有两种方法。
arguments
Object 此对象内置于函数中,它适当地引用函数的参数。但是,从技术上讲,它不是一个阵列,因此典型的阵列操作不会对它起作用。建议的方法是使用Array.from
或扩展运算符从中创建数组。
我已经看到使用slice
提及的其他答案。不要这样做。它会阻止优化(来源:MDN)。
Array.from(arguments)
[...arguments]
但是,我认为arguments
是有问题的,因为它隐藏了函数接受的输入。 arguments
函数通常是这样写的:
function mean(){
let args = [...arguments];
return args.reduce((a,b)=>a+b) / args.length;
}
有时,函数头的编写方式如下所示,以类似C的方式记录参数:
function mean(/* ... */){ ... }
但这种情况很少见。
至于为什么会出现问题,例如以C为例。 C向后兼容被称为K&amp; R C的古老的ANSI前语言.K&amp; R C允许函数原型具有空的参数列表。
int myFunction();
/* This function accepts unspecified parameters */
ANSI C为varargs
(...
)提供了工具,void
用于指定空参数列表。
int myFunction(void);
/* This function accepts no parameters */
许多人无意中使用unspecified
参数列表(int myfunction();
)声明函数,当他们期望函数采用零参数时。这在技术上是一个错误,因为函数将接受参数。任意数量。
C中正确的varargs
函数采用以下形式:
int myFunction(int nargs, ...);
JavaScript确实有类似的东西。
实际上,我已经向你展示了传播运营商。
...name
它非常通用,也可用于函数的参数列表(&#34;休息参数&#34;)以明确记录的方式指定varargs:
function mean(...args){
return args.reduce((a,b)=>a+b) / args.length;
}
或作为lambda表达式:
((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3
我更喜欢传播运营商。这是清洁和自我记录。
答案 4 :(得分:7)
apply
函数有两个参数;对象this
将绑定到,参数用数组表示。
some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
答案 5 :(得分:5)
它被称为splat
运算符。您可以使用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);
答案 6 :(得分:4)
在ES6中,您可以将varagrs
用于rest parameters。这将使用参数列表并将其转换为数组。
function logArgs(...args) {
console.log(args.length)
for(let arg of args) {
console.log(arg)
}
}
答案 7 :(得分:2)
(function(window) {
var proxied = window.alert;
window.alert = function() {
return proxied.apply(window, arguments);
};
}(this));
alert(13, 37);
答案 8 :(得分:2)
这是一个示例程序,用于计算变量参数和整数数组的整数之和。希望这会有所帮助。
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);
答案 9 :(得分:1)
对于那些从Passing variable number of arguments from one function to another重定向的人(不应标记为此问题的副本):
如果您尝试将可变数量的参数从一个函数传递到另一个函数,那么从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".
注意:第一个参数是要使用的this
参数。传递null
将从全局上下文中调用该函数,即作为全局函数而不是某个对象的方法。
根据this document,ECMAScript 5规范重新定义了apply()
方法以获取任何“类通用数组对象”,而不是严格意义上的数组。因此,您可以直接将arguments
列表传递给第二个函数。
在Chrome 28.0,Safari 6.0.5和IE 10中测试过。使用this JSFiddle进行测试。
答案 10 :(得分:0)
是的,您可以传递变量号。函数的参数。您可以使用apply
来实现此目的。
E.g:
var arr = ["Hi","How","are","you"];
function applyTest(){
var arg = arguments.length;
console.log(arg);
}
applyTest.apply(null,arr);
答案 11 :(得分:0)
您是否希望函数对数组参数或变量参数做出反应?如果是后者,请尝试:
var func = function(...rest) {
alert(rest.length);
// In JS, don't use for..in with arrays
// use for..of that consumes array's pre-defined iterator
// or a more functional approach
rest.forEach((v) => console.log(v));
};
但是如果您想处理数组参数
var fn = function(arr) {
alert(arr.length);
for(var i of arr) {
console.log(i);
}
};