我知道JavaScript函数可以接受“任意”数量的参数。
function f(){};
f(1,2,3,4 /*...*/);
但是我想知道实际上有多少个“任何”个数是否有限制?
例如,假设我向提出了一百万个论点f()。那行得通吗?还是口译员会弯腰?
我猜测最大值是(a)特定于实现的(b)(2^32)-1,因为arguments对象是类似数组的。
我在语言规范中没有看到这一点,但是我可能没有连接一些点。
我知道JavaScript函数可以接受“任意”数量的参数。
function f(){};
f(1,2,3,4 /*...*/);
但是我想知道实际上有多少个“任何”个数是否有限制?
例如,假设我向提出了一百万个论点f()。那行得通吗?还是口译员会弯腰?
我猜测最大值是(a)特定于实现的(b)(2^32)-1,因为arguments对象是类似数组的。
我在语言规范中没有看到这一点,但是我可能没有连接一些点。
Function.prototype.apply。 stackoverflow.com/questions/1379553/…–
Math.max或的函数Array.prototype.concat(...arrayOfArrays)(或展平数组的数组),也可以动态达到该限制,而无需编写monster函数。jfriend00提到的开销并不总是很重要-代码的清晰性比几个字节的内存或CPU周期更为重要,在这方面,扩展语法有时可能是最佳选择。看看在“扁平化阵列”替代我的短代码...
Answers:
尽管没有具体限制规范中参数的理论最大数量(如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的arguments数组太大
Internet Explorer 11:上一次成功的测试是131071自变量。之后,它失败并显示:
RangeError:SCRIPT28:堆栈空间不足
Opera 12.17:最近一次成功的测试是1048576自变量。之后,它失败并显示:
错误:Function.prototype.apply:argArray太大
当然,这里可能还有其他因素,您可能会有不同的结果。
这是使用创建的替代提琴eval。同样,您可能会得到不同的结果。
Chrome 33.0.1750.154 m:最近一次成功的测试是32767个参数。之后,它失败并显示:
未捕获的SyntaxError:函数调用中的参数过多(仅允许32766)
这一点特别有趣,因为Chrome本身似乎对实际上允许多少个参数感到困惑。
Firefox 27.0.1:最近一次成功的测试是32767个参数。之后,它失败并显示:
脚本太大
Internet Explorer 11:上一次成功的测试是32767个参数。之后,它失败并显示:
RangeError:SCRIPT7:内存不足
Opera 12.17:最近一次成功的测试是4194303自变量。之后,它失败并显示:
记不清; 脚本已终止。
apply参数并以形式发送参数Array,则无论实际限制是多少(?),每个规范的理论最大值为4,294,967,295个元素。
.apply()似乎更有可能。但是后来他没有提及.apply(),所以也许他正计划做些事情eval。
List类型用于解释新表达式,函数调用以及其他需要简单值列表的算法中对参数列表(请参见11.2.4)的求值。这些序列可以是任意长度。
因此,该标准没有限制。当然,如果您的代码在现实世界中运行,而不是在标准地区运行,则显然存在一些限制(例如,宇宙中的粒子数量)。
有两种方法可以将参数传递给函数。
f(a, b, c)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问题,讨论了参数限制。
List类型用于解释在新表达式,函数调用以及需要简单值列表的其他算法中对参数列表(请参见11.2.4)的求值。List类型的值只是值的有序序列。这些序列可以是任何长度。
因此,该标准对参数的数量没有任何限制,仅受内存限制。
它完全取决于客户端的功能。
因为浏览器将失去记忆,所以如果您要传递数百万个参数。
每个变量都保存一些内存。因此,浏览器将不会为每个变量分配一些内存,直到它本身没有可运行的内存为止。
根据MDN的JavaScript Function部分,函数可以接受的最大参数数量为255。
https://developer.mozilla.org/zh-CN/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.