JavaScript函数可以接受最大数量的参数吗?

时间:2014-03-30 17:12:25

标签: javascript

我知道JavaScript函数可以接受"任何"争论的数量。

function f(){};
f(1,2,3,4 /*...*/);

但是我想知道实际上有多少"任何"可以吗?

例如,让我说我向f()提出了一百万个论点。那会有用吗?或者口译员会翻过来吗?

我猜测最大值是(a)特定于实现或(b)(2^32)-1,因为arguments对象是类似数组的。

我没有在语言规范中看到这一点,但我可能没有连接一些点。

8 个答案:

答案 0 :(得分:76)

虽然没有具体限制规范中理论最大参数数量(如thefortheye's answer所指出)。当然有实用限制。这些限制完全取决于实现,很可能也完全取决于 你如何调用该函数。


我创建了this fiddle作为实验。

function testArgs() {
    console.log(arguments.length);
}

var argLen = 0;
for (var i = 1; i < 32; i++) {
    argLen = (argLen << 1) + 1;
    testArgs.apply(null, new Array(argLen));
}

以下是我的结果:

  • Chrome 33.0.1750.154 m:上一次成功的测试是 65535 参数。之后失败了:

      

    未捕获RangeError:超出最大调用堆栈大小

  • Firefox 27.0.1:上一次成功的测试是 262143 参数。之后失败了:

      

    RangeError:传递给Function.prototype.apply的arguments数组太大

  • Internet Explorer 11:最后一次成功的测试是 131071 参数。之后失败了:

      

    RangeError:SCRIPT28:堆栈空间不足

  • Opera 12.17:最后一次成功的测试是 1048576 参数。之后失败了:

      

    错误:Function.prototype.apply:argArray太大

当然,这里可能还有其他因素可能会有不同的结果。


这是使用eval创建的alternate fiddle。同样,您可能会得到不同的结果。

  • Chrome 33.0.1750.154 m:上一次成功的测试是 32767 参数。之后失败了:

      

    Uncaught SyntaxError:函数调用中的参数太多(仅允许32766)

    这个特别有趣,因为Chrome本身似乎对实际允许的参数数量感到困惑。

  • Firefox 27.0.1:上一次成功的测试是 32767 参数。之后失败了:

      

    脚本太大

  • Internet Explorer 11:上一次成功的测试是 32767 参数。之后失败了:

      

    RangeError:SCRIPT7:内存不足

  • Opera 12.17:最后一次成功的测试是 4194303 参数。之后失败了:

      

    内存不足;脚本终止。

答案 1 :(得分:21)

ECMAScript 5.1, part 8.8

  

List类型用于解释新表达式,函数调用以及需要简单值列表的其他算法中的参数列表(见11.2.4)的评估....这些序列可能是任何长度。

因此标准没有限制。当然,如果您的代码在现实世界中运行,而不是在标准版本中运行,那么显然存在某些限制(例如,Universe中的粒子数)。

将参数传递给函数有两种方法。

  • &#34;字面意思&#34;:f(a, b, c)
  • 使用apply():f.apply(null, [a, b, c])

对于大型参数列表,后一种方式更为实际。

转到此JSFiddle,查看当前浏览器的每个限制。

我自己试了几个浏览器:

           | apply() | literal
 ----------------------------
Chrome 14  | 131155  |  32767
Chrome 35  | 126213  |  65535
Firefox 30 | 500001  |  65535
IE 9       | 254335  |  65533
IE 10      | 253667  |  65533
IE 11      | 252447  |  65533
Opera 22   | 126063  |  65535
Safari 4   | 524215  | 524205
Safari 7   |  65537  | 522159

我在不同的机器上看到了许多这些数字的差异,所以我相信除了浏览器(OS?)之外还有其他因素在起作用。


这是一个真正的问题,不是一些琐事。一个现实世界的例子:

Google Closure Library定义了以下功能。

goog.crypt.byteArrayToString = function(array) {
  return String.fromCharCode.apply(null, array);
};

仅当字符串的长度在可以使用Function.prototype.apply传递的参数数量的浏览器限制范围内时,此方法才有效。

该功能后来patched,使功能更加复杂。


仅供参考,2012年3月提交了一份开放式Webkit issue,其中讨论了参数限制。

答案 2 :(得分:6)

根据ECMA Script 5.1 Standard Specification for List

  

List类型用于解释新表达式,函数调用以及需要简单值列表的其他算法中的参数列表(见11.2.4)的评估。 List类型的值只是有序的值序列。 这些序列可以是任意长度。

因此,该标准对参数的数量没有任何限制,仅受内存的限制。

答案 3 :(得分:2)

Computer Stupidities
&GT;来自计算机愚蠢

就我而言,极限是足够大&#34;!

答案 4 :(得分:1)

它纯粹取决于客户的强大程度。

因为浏览器会丢失内存,如果你要传递数百万个论点。

每个变量都有一些内存。因此,浏览器在将每个变量分配给某个内存时没有问题,直到它本身没有可以运行的内存为止。

答案 5 :(得分:1)

只需将地图(只是一个对象)用作单个参数。您仍然可以使用参数名称,并且可以根据需要使用任意数量的参数。它保证了您可以传入的理论上无限数量的参数,但是显然您仍然受到堆空间的限制。

let infiniteParameters = (w) => console.table(w);

infiniteParameters({
  name1 : "value1",
  name2 : "value2",
  // ...
});

答案 6 :(得分:0)

以下是我检查的方法。

let args = [];

while(true){
    try{
        (() => {})(...args);
        args.push(0);
    }catch(e){
        console.log(e.message);
        console.log(`Number of arguments: ${args.length}`);
        break;
    }
}

答案 7 :(得分:0)

根据MDN的JavaScript函数部分,函数可以接受的最大参数数量为255

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Defining_functions

param The name of an argument to be passed to the function. A function can have up to 255 arguments.