簡體   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