JavaScript 함수는 “임의의”인수를 받아 들일 수 있다는 것을 알고 있습니다.
function f(){};
f(1,2,3,4 /*...*/);
하지만 실제로 얼마나 많은 “무엇”이 될 수 있는지에 대한 제한이 있는지 궁금합니다.
예를 들어, f()
. 작동할까요? 아니면 통역사가 넘어 질까요?
객체가 배열과 유사하기 (2^32)-1
때문에 최대 값이 (a) 구현 별 또는 (b) 중 하나라고 추측하고 arguments
있습니다.
나는 이것이 언어 사양에 언급되어 있지 않지만 일부 점을 연결하지 않을 수 있습니다.
답변
사양의 이론적 최대 인수 수를 제한하는 특정 사항은 없지만 ( theye 의 답변이 지적했듯이). 물론 실제적인 한계가 있습니다. 이러한 제한은 전적으로 구현에 따라 다르며 대부분 함수를 호출하는 방법에 따라 달라집니다 .
이 바이올린 을 실험으로 만들었습니다 .
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 개의 인수입니다. 그 후 실패했습니다.
RangeError : SCRIPT7 : 메모리 부족
-
Opera 12.17 : 마지막으로 성공한 테스트는 4194303 개의 인수입니다. 그 후 실패했습니다.
메모리 부족; 스크립트가 종료되었습니다.
답변
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
나는 다른 컴퓨터에서 이러한 숫자의 많은 차이를 보았 기 때문에 브라우저 (OS?) 외에 다른 요인이 있다고 생각합니다.
이것은 퀴즈 가 아니라 실제 문제 입니다. 실제 예 :
Google Closure Library는 다음 기능을 정의했습니다.
goog.crypt.byteArrayToString = function(array) {
return String.fromCharCode.apply(null, array);
};
이것은 문자열의 길이가와 함께 전달할 수있는 인수 수에 대한 브라우저 제한 내에있는 경우에만 작동했습니다 Function.prototype.apply
.
이 함수는 나중에 패치 되어 함수가 훨씬 더 복잡해졌습니다.
참고로 2012 년 3 월에 인수 제한을 논의 하는 공개 된 Webkit 문제가 있습니다.
답변
에 대한 ECMA 스크립트 5.1 표준 사양에List
따르면 ,
List 유형은 새 표현식, 함수 호출 및 간단한 값 목록이 필요한 기타 알고리즘에서 인수 목록 (11.2.4 참조)의 평가를 설명하는 데 사용됩니다. 목록 유형의 값은 단순히 순서가 지정된 값 시퀀스입니다. 이러한 시퀀스는 임의의 길이 일 수 있습니다.
따라서 표준은 인수 수에 제한이 없으며 메모리에 의해서만 제한됩니다.
답변
> Computer Stupidities에서
내가 아는 한 한계는 “충분히 크다”!
답변
순전히 클라이언트가 얼마나 강력한 지에 달려 있습니다.
수백만 개의 인수를 전달하면 브라우저는 메모리를 잃게됩니다.
각 변수는 약간의 메모리를 보유합니다. 따라서 브라우저는 실행할 메모리가 없을 때까지 각 변수에 메모리를 할당하는 데 문제가 없습니다.
답변
맵 (객체 만)을 단일 매개 변수로 사용하십시오. 여전히 매개 변수 이름을 사용하고 원하는만큼 인수를 가질 수 있습니다. 그것은 당신이 전달할 수있는 이론적 인 무한한 수의 인수를 보장하지만, 당신은 여전히 힙 공간에 의해 제한되어 있습니다.
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;
}
}