변수 수의 매개 변수를 수락하고 "포워드"하는 JS 함수를 작성하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1619850

문제

가변 수의 매개 변수를 받아들이고 모든 매개 변수를 다른 익명 함수로 전달하는 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');
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top