JavaScript 可变数量的函数参数

IT技术 javascript function arguments argument-passing
2021-01-31 10:37:53

有没有办法允许 JavaScript 中的函数的“无限”变量?

例子:

load(var1, var2, var3, var4, var5, etc...)
load(var1)
6个回答

当然,只需使用arguments对象。

function foo() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
有趣的是,Javascript 中的 Array 方法被定义为可以在任何具有length属性的对象上工作这包括arguments对象。知道了这一点,并且该方法concat返回一个副本,这就是所谓的“阵”的,我们可以很容易地转换arguments对象,以这样一个真正的数组:var args = [].concat.call(arguments)有些人更喜欢用它Array.prototype.concat.call来代替,但我喜欢[],它们又短又甜!
2021-03-11 10:37:53
@YasirJan 使用 [...arguments].join()
2021-03-11 10:37:53
已弃用此功能已从 Web 标准中删除。虽然一些浏览器可能仍然支持它,但它正在被删除。尽可能避免使用它并更新现有代码;请参阅本页底部的兼容性表以指导您的决定。请注意,此功能可能随时停止工作。
2021-03-21 10:37:53
这个解决方案最适合我。谢谢。关于参数关键字HERE 的更多信息
2021-03-27 10:37:53
arguments是一个特殊的“类数组”对象,这意味着它有一个长度,但没有其他数组函数。有关更多信息,请参阅developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...以及此答案:stackoverflow.com/a/13145228/1766230
2021-04-03 10:37:53

在(大多数)最近的浏览器中,您可以使用以下语法接受可变数量的参数:

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

+1 这是优雅而干净的解决方案。特别适合将长参数列表传递到另一个函数调用中,并且这些可变参数可能位于任意位置。
2021-03-11 10:37:53
仅供参考,它被称为“其余参数语法”:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-18 10:37:53
这是一个显示浏览器支持的表格 - caniuse.com/#feat=rest-parameters
2021-03-19 10:37:53
这么好的答案!
2021-03-20 10:37:53
请记住,根据developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ... IE 不支持它。
2021-03-23 10:37:53

另一种选择是在上下文对象中传递您的参数。

function load(context)
{
    // do whatever with context.name, context.address, etc
}

并像这样使用它

load({name:'Ken',address:'secret',unused:true})

这样做的好处是您可以根据需要添加任意数量的命名参数,并且函数可以根据需要使用(或不使用)它们。

这也很好,因为如果你愿意,你可以context用代码构建参数并在它被使用之前传递它。
2021-03-19 10:37:53
这会更好,因为它消除了与参数顺序的耦合。松散耦合的接口是良好的标准实践......
2021-03-25 10:37:53
当然,这在某些情况下更好。但是假设单个参数彼此之间并不真正相关,或者都应该具有相同的含义(如数组元素)。那么OP的方式是最好的。
2021-03-27 10:37:53

我同意 Ken 的回答是最有活力的,我喜欢更进一步。如果它是一个使用不同参数多次调用的函数 - 我使用 Ken 的设计,然后添加默认值:

function load(context) {

    var defaults = {
        parameter1: defaultValue1,
        parameter2: defaultValue2,
        ...
    };

    var context = extend(defaults, context);

    // do stuff
}

这样,如果您有很多参数但不一定需要在每次调用函数时都设置它们,您可以简单地指定非默认值。对于扩展方法,您可以使用 jQuery 的扩展方法 ( $.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];
}

这会将上下文对象与默认值合并,并使用默认值填充对象中的任何未定义值。

Underscore 的 _.defaults()方法是合并指定参数和默认参数的非常好的替代方法。
2021-03-24 10:37:53
+1。不错的把戏。节省大量样板以定义每个参数,默认或其他。
2021-04-06 10:37:53

正如 Ramast 指出的那样,最好使用 rest 参数语法。

function (a, b, ...args) {}

我只想添加 ...args 参数的一些不错的属性

  1. 它是一个数组,而不是像参数这样的对象。这允许您直接应用 map 或 sort 等功能。
  2. 它不包括所有参数,而只包括从它传递过来的参数。例如 function (a, b, ...args) 在这种情况下 args 包含参数 3 到arguments.length