是否可以向一个 JavaScript 函数发送数量可变的参数?

有没有可能从一个数组中向一个 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 并发送它们是一种很棒的模式。例如:。

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 中发送一个数组来处理 作为的参数数组?

146560 次浏览

更新 : 从 ES6开始,您可以简单地在调用函数时使用 扩展语法:

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值,那么可以这样做。

下面是一个 申请的例子,它是以前的方法:

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);

现在,我只建议在需要从数组 还有传递任意数量的参数设置 this值时才使用 applyapplythis值作为第一个参数,它将用于函数调用,如果我们在非严格代码中使用 null,那么 this关键字将引用 func中的 Global 对象(窗口) ,在严格模式下,当显式使用“ use strong”或 ES 模块时,将使用 null

还要注意的是,arguments对象实际上不是 Array,您可以通过以下方式转换它:

var argsArray = Array.prototype.slice.call(arguments);

在 ES6中:

const argsArray = [...arguments] // or Array.from(arguments)

但是由于扩展语法,现在很少直接使用 arguments对象。

实际上,您可以向任何 javascript 函数传递任意多的值。显式命名的参数将获得前几个值,但 ALL 参数将存储在参数数组中。

要以“ unpack”形式传递参数数组,您可以使用 application,如下所示(c.f函数式 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);

apply函数接受两个参数; 对象 this将被绑定到,参数用数组表示。

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"

它被称为 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);

对于那些从 将变量数目的参数从一个函数传递到另一个函数重定向到这里的人(没有应该被标记为这个问题的重复) :

如果您试图从一个函数向另一个函数传递数量可变的参数,那么从 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将从全局上下文调用函数,即作为全局函数而不是某个对象的方法。

根据 这份文件,ECMAScript 5规范重新定义了 apply()方法以接受任何“类似数组的通用对象”,而不是严格意义上的 Array。因此,可以直接将 arguments列表传递给第二个函数。

在 Chrome28.0,Safari6.0.5和 IE10中测试过。

传播操作符是 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');

请注意传播的笨拙语法。通常的 sprintf('The %s %s fox jumps over the %s dog.', ...arr);语法是 尚未得到支持。您可以找到 这里有一个 ES6兼容性表

还要注意使用 for...of,另一个 ES6附加。

(function(window) {
var proxied = window.alert;
window.alert = function() {
return proxied.apply(window, arguments);
};
}(this));


alert(13, 37);

这是一个用于计算变量参数和整数数组的整数和的示例程序。希望对您有所帮助。

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);

到 ES2015为止,有两种方法。

arguments对象

这个对象被内置到函数中,它适当地引用函数的参数。但是,从技术上讲,它不是一个数组,所以典型的数组操作对它不起作用。建议的方法是使用 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 是向后兼容的一种古老的前 ANSI 方言的语言称为 K & R C。 K & 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 实际上也有类似的东西。

展开操作符 /< a href = “ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/function/Rest _ properties”rel = “ noReferrer”> REST 参数

实际上,我已经给你看过扩展运算符了。

...name

它的用途非常广泛,也可以用在函数的参数列表(“静态参数”)中,以文档化的方式指定 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

我更喜欢传播操作员。它是干净和自我记录。

是的,您可以将变量 no. of 参数传递给函数。您可以使用 apply来实现这一点。

例如:

var arr = ["Hi","How","are","you"];


function applyTest(){
var arg = arguments.length;
console.log(arg);
}


applyTest.apply(null,arr);

对于 ES6,您可以使用 剩余参数来表示 varagrs。这将获取参数列表并将其转换为数组。

function logArgs(...args) {
console.log(args.length)
for(let arg of args) {
console.log(arg)
}
}

您希望函数对数组参数或变量参数做出反应吗? 如果是后者,请尝试:

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);
}
};