繁体   English   中英

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

[英]Is there a max number of arguments JavaScript functions can accept?

我知道 JavaScript 函数可以接受“任意”数量的参数。

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

但我想知道“任何”的数量是否真的有限制?

例如,假设我将一百万个参数传递给f() 那行得通吗? 还是口译员会倒下?

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

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

尽管没有具体限制规范中的理论最大参数数量(正如thefortheye的回答所指出的那样)。 当然也有实际限制。 这些限制是完全依赖于实现的,最有可能,也将取决于正是你如何调用该函数。


我创建了这个小提琴作为实验。

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 的参数数组太大

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

    RangeError: SCRIPT28: 堆栈空间不足

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

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

当然,这里可能还有其他因素在起作用,您可能会得到不同的结果。


这是使用eval创建的替代小提琴 同样,您可能会得到不同的结果。

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

    未捕获的语法错误:函数调用中的参数过多(仅允许 32766)

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

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

    脚本太大

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

    范围错误:SCRIPT7:内存不足

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

    内存不足; 脚本终止。

ECMAScript 5.1,第 8.8 部分

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

所以标准没有限制。 当然,如果您的代码在现实世界中运行,而不是在标准域中运行,那么显然存在一些限制(例如,宇宙中的粒子数)。

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

  • “字面意思”: 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

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


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

Google Closure 库定义了以下函数。

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

仅当字符串的长度在浏览器限制内可以通过Function.prototype.apply传递的参数数量时,这才有效。

该功能后来被修补,使该功能明显更加复杂。


仅供参考,2012 年 3 月提交的一个开放的Webkit 问题讨论了参数限制。

根据ECMA Script 5.1 Standard Specification for List

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

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

计算机愚蠢
> 来自计算机愚蠢

就我而言,极限是“足够大”!

这完全取决于客户端的强大程度。

因为浏览器会失去它的内存,如果你要传递数百万个参数。

每个变量都有一些内存。 所以浏览器可以毫无问题地为每个变量分配一些内存,直到它本身没有内存可以运行。

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

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

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

这是我检查它的方法。

let args = [];

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

根据 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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM