[英]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 個參數。 之后它失敗了:
內存不足; 腳本終止。
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 問題討論了參數限制。
根據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.