2013-04-10 5 views
8

함수의 배열을 가지고 있으며 각 함수를 순서대로 호출하는 간결한 방법을 찾고 있습니다.목록의 각 함수를 호출하십시오.

fns.map(function (f) { f() }) 

을 등이 수행합니다 :

fns = [ 
    function a() { console.log('a') }, 
    function b() { console.log('b') }, 
    function c() { console.log('c') }, 
] 

이 작동

fns.map(function (f) { Function.call.call(f) }) 

그러나 이것은 형식 오류 제기

fns.map(Function.call.call) 

을하지 않는 이유는 후자의 예 작업 ?

답변

4

이 단순화 된 코드 유사한 문제 나타내는이 경우

var x = Function.call.call; 
x(alert); 

를 한번 Function.call.call가 호출되는, 그것의 출발 컨텍스트 (즉 Function.call)를 기억할 것이다.

Function.call.bind(Function.call) 

그것은 Function.call의 상황이 이렇게 컨텍스트를 저장 자체에 바인딩함으로써 새로운 기능을 반환 :이 컨텍스트를 저장하려면,이 신성 구조 트릭을 사용할 수 있습니다. 새 변수에이 표현을 저장할 수 있습니다

var callFn = Function.call.bind(Function.call); 

이제 callFn(alert)alert.call() 동일합니다. 추가 인수는 그대로 따라 전달되므로 callFn(alert, window)alert.call(window)을 호출합니다. 이 Array.forEach과 같이 콜백의 일부로 호출되면 각 반복에서 세 개의 인수가 전달되는 상황에서이 동작을 이해하는 것이 중요합니다. 귀하의 경우에는

fns.forEach(callFn); 

, fns 내부의 기능 중 어느 것도 전달되는 인수를 사용하지 않습니다,하지만 무대 뒤에서 그들은 다음과 같이라는 것 : 그래서 this이 요소의 인덱스 (동일

fns[0].call(0, fns) 

Number(0))이고 arguments[0]은 함수 배열과 같습니다. 예리한 관찰자는 요소의 값이 균열 사이에 있음을 알 수 있지만 여전히 arguments[0][this] 또는 대체적으로 arguments.callee (사용되지 않음)을 사용하여 참조 할 수 있습니다.

+0

빙고, 그게 다야! 많은 감사합니다. – georg

+0

인수에 대한 후속 조치가 잘되었지만 '호출 수신자'가 아닌 이유는 무엇입니까? 단순히'인수 [0] [this]'에 무엇이 잘못 되었습니까? – georg

+0

@ thg435 좋은 지적입니다. 이 경우 작동합니다 :) 감사합니다! –

5
for (var i = 0, len = fns.length; i < len; i++) { 
    fns[i].call(); 
}; 

여기에 작동은 fiddle입니다.

위와 같이 Function.prototype.callFunction.prototype.apply을 사용하여 함수를 호출하십시오. callapply을 사용하면 실행 범위와 arguments을 함수 호출에 전달할 수 있습니다. 당신이 필요하지 않은 경우, 당신은 간단하게 수행 할 수 있습니다

for (var i = 0, len = fns.length; i < len; i++) { 
     fns[i](); 
}; 

을 코드에 관하여 :

Array.prototype.mapcallbackscope as parameters를받는 함수이다. 처음 두 예제에서는 익명 함수를 callback으로 사용하고 전달 된 매개 변수를 Array.prototype.map으로 자동 호출합니다. 확장하려면 코드는 다음과 같습니다.

function single(element) { 
    element(); 
}; 
fns.map(single); 

위의 내용은 완전히 정확합니다. 동일한 원칙에 따라 Function.call.call을 사용하면 f 함수를 map으로 매개 변수로 전달합니다.

그러나 세 번째 예를 들어 당신이 그러나이 경우, Function.call.prototype.call를 통해 직접 call을 강요

f 더 이상 Function.call.call은 따라서 당신이 TypeError를 얻을 undefined를 호출하려고 시도합니다 의미 매개 변수로 전달되지됩니다. Function.call.callmap() 안에 넣으면 이 아니며callback을 인수로 전달합니다.

call은 즉시 처리됩니다. Function.call.callFunction.call.call() 또는 Function.call.call(undefined)과 완전히 똑같은데 세 번째 예에서 사용한 것처럼 사용하면 즉시 평가됩니다.

+3

OP는 이미 모든 것을 이미 알고 있습니다. 질문은 * 왜 *, * *가 아닌지 묻습니다. – Jon

+0

그동안 나는 실제로 같은 것을 쓰고있었습니다! +1 – Jon

3

TypeErrorFunction.prototype.call이 내부적으로 주어진 컨텍스트와 매개 변수를 사용하여 this을 호출하기 때문에 발생합니다.하지만 이는 논의에서 중요하지 않습니다.

은 이제 동등한

fns.map(function (f) { 
    var invoker = Function.call; 
    invoker.call(f); 
}) 

그것은 invokerthisf를 호출 이제 분명한 것입니다으로 작업

fns.map(function (f) { Function.call.call(f) }) 

을 다시 보자. 내부적으로 this을 호출하려고하면 예상대로 함수가 호출됩니다.

fns.map(Function.call.call); 

그리고 여기, invokerthis를 호출 할 때 그 undefined이다 명백해야한다

fns.map(function (f) { 
    var invoker = Function.call; 
    invoker.call(); 
}) 

에 해당하는 형태;

지금 이것 좀 봐 따라서 자체적으로 호출 할 수 없으므로 TypeError이 발생합니다.

관련 문제