변수 수의 매개 변수를 수락하고 "포워드"하는 JS 함수를 작성하는 방법은 무엇입니까?
-
06-07-2019 - |
문제
가변 수의 매개 변수를 받아들이고 모든 매개 변수를 다른 익명 함수로 전달하는 JavaScript 함수를 어떻게 작성합니까?
예를 들어, 이벤트를 시작하는 메소드의 시나리오를 고려하십시오.
function fireStartedEvent(a,b,c,d,e,f,g,...) {
for(var i = 0; i < startedListeners.length; i++) {
startedListeners[i](a,b,c,d,e,f,g,...);
}
}
특히 이러한 화재 방법을 생성하는 이벤트 공장이 있기 때문에 이러한 방법은 주어진 이벤트 또는 해당 핸들러가 소비하는 매개 변수의 수를 아는 데 관심이 없습니다. 그래서 나는 지금 7시 (a ~ g)에 열심히 연결했습니다. 더 적은 경우 문제가 없습니다. 더 이상이라면 끊어집니다. 어떻게 캡처하고 전달할 수 있습니까? 모두 매개 변수?
감사.
(jQuery 또는 기타 JavaScript 프레임 워크를 사용하는 것은 여기서 옵션이 아닙니다.)
해결책
이를 해결하려면 두 가지 JavaScript 개념에 대한 지식이 필요합니다.
첫 번째는 특별한 것입니다 arguments
이름을 모르고 기능 인수에 액세스하는 데 사용할 수있는 로컬 변수는 배열처럼 작동합니다. 하지만, arguments
~이다 ~ 아니다 an Array
, 그러나 "배열과 같은" - 특성이 이름이 붙은다. 0..n-1
, 어디 n
함수에 대한 인수의 수는 length
속성 - 개체. 간단한 데모 사용법은 다음과 같습니다.
function f (a) { // can include names still, if desired
// arguments instanceof Array -> false (exceptions to this?)
var firstArg = arguments[0]
// a === firstArg -> always true
// iterate all arguments, just as if it were an Array:
for (var i = 0; i < arguments.length; i++) {
alert(i + " : " + arguments[i])
}
}
f("a","b","c")
두 번째 기능은입니다 Function.apply
특정 컨텍스트가있는 함수를 호출합니다 (this
그것이 호출 될 때) 확장 "배열과 같은"객체의. 하지만 참조하십시오 1.
따라서 합쳐서 :
function fireStartedEvent() {
for(var i = 0; i < startedListeners.length; i++) {
// jQuery will often pass in "cute" things, such as a element clicked
// as the context. here we just pass through the current context, `this`,
// as well as the arguments we received.
var arg = Array.prototype.slice.call(arguments)
startedListeners[i].apply(this, args)
}
}
1 ecmascript 사양은 "배열과 같은"개체 만 요구하지만 Function.apply
하지 않습니다 "배열과 같은 배열"객체 및 여러 공통 구현으로 보편적으로 작동합니다. 필요하다 적절한 Array
물체. 경고 Function.apply
링크:
메모: 대부분의 브라우저를 포함합니다 크롬 14 그리고 인터넷 익스플로러 9, 여전히 객체와 같은 배열을 허용하지 않으며 예외가 발생하지 않습니다 [비 어울리 객체가 통과되는 경우]. Firefox는 버전 4에서 고정되었습니다.
고맙게도, "배열과 같은"객체를 Array
(왜냐하면 그것은 아이러니합니다 Array.slice
하다 "배열과 같은"개체와 보편적으로 작업) :
var args = Array.prototype.slice.call(arguments);
(그리고 args
보편적으로 사용될 수 있습니다 Function.apply
.)
다른 팁
"적용"과 "인수"는 여기에서 사용할 수있는 두 가지 JavaScript 개념이라고 생각합니다.
function fireStartedEvent() {
for (var i = 0; i < startedListeners.length; i++) {
startedListeners[i].apply(startedListeners[i], arguments);
}
}
다음은 내 Firebug 콘솔의 코드입니다.
a = function(foo) { alert('a: ' + foo); };
b = function(foo, bar) { alert('b: ' + foo + ', ' + bar); };
startedListeners = [a, b];
function fireStartedEvent() {
for (var i = 0; i < startedListeners.length; i++) {
startedListeners[i].apply(startedListeners[i], arguments);
}
}
fireStartedEvent('one', 'two');