munifico.github.io

munifico's anything page

Follow me on GitHub

함수에 함수 전달

함수에 함수를 전달하는 예제는 setTimeout과 forEach에서 이미 봤습니다. 함수에 함수를 전달하는 다른 용도는 비동기적 프로그래밍입니다. 이런 용도로 전달하는 함수를 보통 콜백callback이라 부르며, 약자로 cb를 쓸 때가 많습니다. 콜백 함수는 자신을 감싼 함수가 실행을 마쳤을 때 호출됩니다. 콜백은 14장에서 자세히 설명합니다.

함수에 함수를 전달하는 대표적인 사례가 콜백이긴 하지만, 그게 전부는 아닙니다. 함수는 동작이고, 함수를 받은 함수는 그 동작을 활용할 수 있습니다. 배열에 들어있는 숫자를 모두 더하는 단순한 함수 sum이 필요하다고 합시다(배열에 숫자가 아닌 것이 들어있을 때를 대비한 체크나 에러 처리는 생략하겠습니다). 그런 함수는 쉽게 만들 수 있습니다. 그런데 숫자의 제곱square을 합해서 반환하는 함수가 필요하다면? 물론 새 함수 sumOfSquares를 만들어도 됩니다. 그런데, 세제곱을 합해서 반환하는 함수도 필요하다면? 이런 상황에서 함수에 함수를 전달한다는 발상이 필요합니다. sum을 이렇게 만들었다고 합시다.

function sum(arr, f) {
    //함수가 전달되지 않았으면 매개변수 그대로를 반환하는 null 함수를 씁니다.
    if(typeof f != 'function') f = x => x;

    return arr.reduce((a, x) => a += f(x), 0);
}

sum([1,2,3]);                       //6
sum([1,2,3], x => x*x);             //14
sum([1,2,3], x => Math.pow(x,3));   //36

임의의 함수를 sum에 전달하면 원하는 일을 거의 모두 할 수 있습니다. 제곱근의 합이 필요한가요? 아무 문제도 없습니다. 숫자의 4.233 제곱의 합이 필요한가요? 바로 할 수 있습니다. sum을 바로, 즉 함수를 넘기지 않고 호출해야 할 수도 있습니다. 함수를 넘기지 않고 sum을 호출하면 매개변수 f의 값은 undefined이므로 에러가 일어납니다. 에러를 방지하기 위해 함수가 아닌 것은 모두 ‘null 함수’, 즉 아무 일도 하지 않는 것으로 바꿉니다. 즉 null 함수 f에 5를 넘기면 그대로 5를 반환합니다. 배열의 모든 요소에서 null 함수를 호출하는 것보다는 요소를 그냥 더하는 함수를 한 번 호출하는 등 더 효율적인 방법이 물론 있겠지만, 이런 식으로 ‘안전한’ 함수를 만들 수 있다는 걸 충분히 이해했을 겁니다.


이전 : 배열 안의 함수
다음 : 함수를 반환하는 함수
목차