JavaScript函数可以接受的最大参数数量是多less?
我知道JavaScript函数可以接受任意数量的参数。
function f(){}; f(1,2,3,4 /*...*/);
但是我想知道是否有限制多less“任何”可以?
例如,假设我向f()
传递了一百万个参数。 这会工作吗? 或者解释者龙卷风了?
我猜测最大值是(a)实现特定的或(b) (2^32)-1
,因为arguments
对象是类似数组的。
我在语言规范中没有看到这一点,但我可能不会连接点。
虽然没有什么具体限制规范的理论上的最大数量的论据(正如他的答案指出的那样)。 当然有实际的限制。 这些限制完全取决于实现,很可能也取决于你如何调用函数。
我创造了这个小提琴作为一个实验。
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:最后一次成功的testing是65535个参数。 之后,它失败了:
未捕获的RangeError:超出最大调用堆栈大小
-
Firefox 27.0.1:最后一次成功的testing是262143个参数。 之后,它失败了:
RangeError:传递给Function.prototype.apply的参数数组太大
-
Internet Explorer 11:最后一次成功的testing是131071个参数。 之后,它失败了:
RangeError:SCRIPT28:堆栈空间不足
-
Opera 12.17:最后一次成功的testing是1048576个参数。 之后,它失败了:
错误:Function.prototype.apply:argArray太大
当然,这里可能还有其他因素,你可能会有不同的结果。
这里是使用eval
创build的替代小提琴 。 再次,你可能会得到不同的结果。
-
Chrome 33.0.1750.154 m:最后一次成功的testing是32767个参数。 之后,它失败了:
未捕获的SyntaxError:函数调用中的参数太多(只允许32766)
这一点特别有趣,因为Chrome本身似乎对实际允许多less个参数感到困惑。
-
Firefox 27.0.1:最后一次成功的testing是32767个参数。 之后,它失败了:
剧本太大了
-
Internet Explorer 11:最后一次成功的testing是32767个参数。 之后,它失败了:
RangeError:SCRIPT7:内存不足
-
Opera 12.17:最后一次成功的testing是4194303个参数。 之后,它失败了:
内存不足; 脚本终止。
ECMAScript 5.1,第8.8部分
Listtypes用于解释在新的expression式,函数调用和需要简单列表值的其他algorithm中对参数列表(参见11.2.4)的评估。这些序列可以是任意长度的。
所以标准没有限制。 当然,如果你的代码在真实世界中运行,而不是在标准域中运行,那么显然有一些限制(例如宇宙中的粒子数量)。
有两种方法将parameter passing给函数。
- “字面上”:
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库定义了以下function。
goog.crypt.byteArrayToString = function(array) { return String.fromCharCode.apply(null, array); };
这只有在string的长度在可以通过Function.prototype.apply
传递的参数数量的浏览器限制内时才起作用。
该function后来被修补 ,使function显着更复杂。
仅供参考,2012年3月提交了一个开放的Webkit问题 ,讨论了参数限制。
根据ECMA脚本5.1 List
标准规范 ,
Listtypes用于解释在新的expression式,函数调用和需要简单列表值的其他algorithm中对参数列表(见11.2.4)的评估。 Listtypes的值只是有序的值序列。 这些序列可以是任何长度的。
所以,标准对参数数量没有任何限制,只受内存限制。
>从计算机愚蠢
就我而言,限制是“足够大”!
这完全取决于客户的强大程度。
因为浏览器将失去它的内存,如果你要传递数以百万计的论据。
每个variables都包含一些内存。 所以浏览器将没有问题分配每个variables一些内存,直到它本身没有内存运行。