JavaScript 특징의 이해 - JS의 중심 Function 살펴보기(2)

2011. 2. 27. 08:09
Callback Function
먼저 아래의 예제를 살펴봅니다.

function execCode(callback){
//함수내용이 어쩌구 저쩌구
callback();
//이러쿵 저러쿵
}
function makeToy(){
//이리저리 주절주절
}

execCode(makeToy);

위의 예제에서 makeCode함수를 callback함수라고 합니다.
이러한 callback함수는 어디에 사용될까요?

첫번째로 event listener로 사용됩니다.
document.addEventListener("click",eventFunction(),false);
이벤트가 실행될때 어떠함수가 실행되도록 지정하는 것도 일종의 callback함수입니다.

두번째로 Timeout()가 있습니다.
var testFun=function(){
//blah blah....
}
setTimeout(testFun,200);

위의 예와 같이 timeout 인자로 들어가서 동작되는 것도 callback함수 입니다.

Function Hoisting
이것은 함수의 scope와 관련이 있습니다.
함수는 크게 함수리터럴과 함수선언문(declaration)이 있습니다.(지난번 포스팅내용)
함수 실행문이 만약 함수 선언문 보다 앞서서 호출되는 어떻게 될까요? 일반적으로 문제가 없이 동작이 됩니다. 정확히는 함수선언문인 경우에만 오류없이 동작합니다. 함수선언문에서 이러한 이유는 현재의 scope내에서 함수정의문이 가장 위로 올라가기 때문 입니다. 따라서 함수를 어디에 정의해도 동일한 scope내에서는 그 함수를 어디에서 호출하던지 상관 없습니다.

solvin();   //잘 동작합니다. 함수선언문인 경우 hoisting되었기 때문입니다.
nayun();  //오류가 납니다.
function solvin(){}
var nayun = function(){}


하지만 함수 리터럴은 오류가 발생할 수 있습니다. (ie브라우저인경우 함수리터럴인 경우에도 함수이름이 정의되어 있다면 함수선언문과 같이 함수정의를 scope상단으로 이동시킵니다)
여튼 이러한 이유로 함수선언문이 더 일반적인 사용법이라고 볼 수도 있습니다.

위와 같이 함수선언문이 scope내의 맨 위로 올라가는 것을 function hoisting이라고 합니다.
너무 낯선 개념은 아니고, 사실은 자바스크립트 개발자는 이러한 현상이 자연스럽게 생각될 수 있는 것 같습니다.

Parentheses
이것은 보통 실행함수라고 아래와 같은 형태를 가집니다.
function(){//body code}()
위 코드에서 뒷부분 () 을 영어로 parentheses라고 합니다.위의 예는 특별한 경우이고 일반적으로 아래의 경우도 같습니다.
call();
이것은 연산자라는 사실을 기억해야 합니다.
만일 ()를제외하고 함수를 부르면 어떻게 될까요? 이것은 함수를 실행하는 것이 아니고 함수자체를 전달하는 것입니다.  보통 이벤트 핸들러에 함수자체를 전달하기도 하죠

document.onclick = iamfunction;


커링(currying)
커링은 자바스크립트의 여러가지 특징으로 인해 함수를 호출하는 특별한 방법이라고 볼 수 있습니다.
full application이라는 것과, Partial Application을 간단히 이해해야 합니다.

아래의 예제에서 2가지 사례를 볼 수 있습니다.(예제는 Javascript Patterns 라는 책의 80page를 참고)
function sum(x,y) {
 return x+y;
}

//full application
sum.apply(null,[3,4]);

//partial application
var newadd = sum.partialApply(null,[3]);
newadd.apply(null,[4]); 
위의 예제의 full application의 경우에는 apply라는 함수를 사용해서 3,4라는 인자를 받아서 사용하고 있습니다. apply를 일반적인 형태로 사용한 것 뿐인데요. 이런 경우를 full application이라고 부릅니다.

두번째의 경우 한번에 실행 해야 할 것을 나눠서 실행하고 있습니다. 그만큼 파라미터의 개수가 반으로 줄었습니다.이러한 패턴을 partial application이라고 부릅니다.

마치 아래와 같이 동작합니다.
sum(3)(4) //parentheses가 2번실행된 것 같이.

예제에 중요한 포인트는 partialApply라는 함수가 보입니다.
이것이 이처럼 파라미터를 나눠서 실행가능하게 동작해주고 있는데요, 이런 것이 가능하도록 partialApply라는 함수를 구현해 두고 사용하면 됩니다.
이러한 함수의 형태는 인터넷에서도 어렵지 않게 찾을 수 있습니다.

http://westhoffswelt.de/blog/0053_currying_functions_in_javascript.html
http://extralogical.net/articles/2010-08-21-currying-javascript/

대부분 비슷한 방법으로 curry함수를 구현하게 됩니다.
마지막으로 partial application과 currying라는 용어가 혼돈될 수 있는데요, 이것은 굳이 어렵게 구별할 필요는 없는 것 같습니다. 일반적으로 currying은 파라미터의 개수가 한정되어 있지 않습니다. 그렇게 구현하면 되겠죠?
하지만 꼭 그런것만은 아닌것 같습니다.
일반적으로 currying이라는 것은 partial application을 다루는 방법으로 생각하는 것이 좋겠습니다.

다음편에는 아래 내용을 작성 하겠습니다.
- Function Scope(Scope chain이란?)
- call object
- Closure 이해하기

참고
JavaScript Patterns
Javascript The Definitive Guide
자바스크립트 핵심 가이드

니가요 HTML5_JS_CSS , , , , , , , , ,