将未知数量的参数传递给javascript函数


84

有没有办法传递未知数量的参数,例如:

var print_names = function(names) {
    foreach(name in names) console.log(name); // something like this
}

print_names('foo', 'bar', 'baz');

另外,如何获得传入的参数数量?



到目前为止,公共重写的答案是唯一描述如何未知数量的参数(传递给函数调用)(使用.apply的答案。其他示例展示了如何(使用)从函数内部读取未知数量的参数arguments

Answers:


146

ES3(或ES5或老式Javascript)

您可以通过magicarguments对象访问传递给任何javascript函数的参数,该对象的行为类似于数组。使用arguments您的函数看起来像

var print_names = function() {
     for (var i=0; i<arguments.length; i++) console.log(arguments[i]);
}

这是需要注意的重要的arguments不是一个数组。MDC上有一些很好的文档:https : //developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#Using_the_arguments_object

如果你想打开arguments到一个数组,这样就可以做这样的事情.slice().push()等等,使用这样的事情:

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

ES6 /打字稿

有更好的方法!新的rest参数功能为您服务:

var print_names = function(...names) {
    for (let i=0; i<names.length; i++) console.log(names[i]);
}

3
感谢您提供这么详细的答案,同时又简短又简单:)
Mese 2016年

1
ES6的引用在spread syntax这里非常不正确。那是rest parameter你给的例子。好的答案,但令人困惑,它被称为spread
Drenai

感谢您的回答!我发现这是一篇很有帮助的文章,解释了发生了什么事情Array.prototype.slice.call(arguments)medium.com/@andrewsburke/…–
AnnieP

22

ES6 / ES2015

利用rest参数语法

function printNames(...names) {
  console.log(`number of arguments: ${names.length}`);
  for (var name of names) {
    console.log(name);
  }
}

printNames('foo', 'bar', 'baz');

rest参数和arguments对象之间有三个主要区别:

  • 其余参数只是没有给它单独命名的参数,而arguments对象包含传递给函数的所有参数;
  • arguments对象不是真正的数组,rest参数是Array实例,这意味着可以直接在其上应用诸如sort,map,forEach或pop之类的方法;
  • arguments对象具有特定于其自身的其他功能(例如callee属性)。

对于通常使用通用PHP语法的Web开发,这是非常有意义的。
丹丹

13
var 
print_names = function() {
    console.log.apply( this, arguments );
};

print_names( 1, 2, 3, 4 );


6

有一个隐藏的对象传递给JavaScript中称为的每个函数arguments

您将只用于arguments.length获取传递给函数的参数数量。

要遍历参数,可以使用循环:

for(var i = arguments.length; i--) {
   var arg = arguments[i];
}

请注意,这arguments不是真正的数组,因此,如果您需要将其作为数组,则可以将其转换为:

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

3
只要注意,这不是一个“真正”的阵列,它是一个“阵列状”对象(有一些特殊的特征),而是利用它“Array方法”,则需要将其转换,如var args = Array.prototype.slice.call(arguments);var args = Array.apply(null, arguments);等,有很多方法……
Christian C.Salvadó10年

4

arguments.length。您可以在其上使用for循环。

(function () {
    for (var a = [], i = arguments.length; i--;) {
        a.push(arguments[i]);
    };
    return a;
})(1, 2, 3, 4, 5, 6, 7, 8)

@meder,我喜欢使用这样的匿名函数。很好的例子!另外,您是否在那里缺少几个分号?
Jacob Relkin

似乎运行正常。
meder omuraliev 2010年

@ meder,JavaScript #ftf中的分号插入
Jacob Relkin 2010年

@meder,确实,实际上for并不需要分号之后的分号,但是我将在最后一行的末尾添加一个。
Christian C.Salvadó10年

1
@weng,关于FunctionExpressionvs FunctionDeclaration,请查看此文章
Christian C.Salvadó10年

2

ES6现在好多了

function Example() {
    return {
        arguments: (...args) =>{
            args.map(a => console.log());
        }
    }
}

var exmpl = new Example();
exmpl.arguments(1, 2, 3, 'a', 'b', 'c');

我希望这有帮助


0

ES6中的其余参数

const example = (...args) => {
  for (arg in args) {
    console.log(arg);
  }
}

注意:您可以在其余参数之前传递常规参数

const example = (arg1, ...args) => {
  console.log(arg1);
  for (arg in args) {
    console.log(arg);
  }
}

0

您可以使用spread / rest运算符将您的参数收集到数组中,然后length数组的就是您传递的参数数量:

function foo(...names) {
    console.log(names);
    return names;
}

console.log(foo(1, 2, 3, 4).length);

使用BabelJS我将函数转换为oldschool JS:

"use strict";

function foo() {
  for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) {
    names[_key] = arguments[_key];
  }

  console.log(names);
  return names;
}

0

您可以使用价差/余数运算符创建一个函数,然后就可以实现您的目标。请看下面的块。

const print_names = (...args) => args.forEach(x => console.log(x));


-4

我喜欢这样做:

如果您不知道参数的数量,这将无济于事,但如果您不想记住参数的顺序,则无济于事。

/**
 *  @param  params.one        A test parameter
 *  @param  params.two        Another one  
 **/
function test(params) {

    var one = params.one;
    if(typeof(one) == 'undefined') {
        throw new Error('params.one is undefined');
    }

    var two = params.two;
    if(typeof(two) == 'undefined') {
        throw new Error('params.two is undefined');
    }
}

1
问题是未知数量的论点。
由Adrian设计,2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.