자바스크립트의 일급 함수와 고차 함수
2분 읽기
자바스크립트를 처음 배울 때 가장 낯선 장면 중 하나는 함수를 다른 함수의 인자로 넘기는 코드였습니다.
[1, 2, 3].map(function (n) {
return n * 2;
});숫자나 문자열을 넘기는 건 자연스럽지만, 함수를 넘기는 건 처음엔 낯섭니다. 자바스크립트에서 함수는 다른 값과 동등하게 취급되기 때문에 가능한 일입니다. 이처럼 값처럼 다룰 수 있는 함수를 일급 함수(First-class function)라고 합니다.
일급 시민이란 무엇인가요?링크를 제목에 복사
프로그래밍 언어에서 일급 시민이란 다른 요소들과 차별 없이 동등하게 취급되는 대상을 의미합니다. 즉, 변수에 할당하고, 함수의 인자로 전달하고, 함수의 반환값으로 사용할 수 있는 값을 말합니다.
로빈 포플스톤(Robin Popplestone)은 일급 객체를 구성하는 조건을 다음과 같이 정의했습니다.
- 모든 요소는 함수의 실제 매개변수가 될 수 있다.
- 모든 요소는 함수의 반환 값이 될 수 있다.
- 모든 요소는 할당 명령문의 대상이 될 수 있다.
- 모든 요소는 동일 비교의 대상이 될 수 있다.
일급 객체가 왜 중요한가요?링크를 제목에 복사
일급 시민의 조건을 만족하는 객체(Object)를 일급 객체라고 합니다.
일급 객체가 중요한 이유는, 값을 다루듯 함수를 다룰 수 있게 되면서 함수의 조합과 추상화가 자유로워지기 때문입니다. 이는 함수형 프로그래밍의 토대가 됩니다.
일급 함수는 일급 객체와 어떻게 다른가요?링크를 제목에 복사
함수가 일급 함수라면 동시에 일급 객체이며, 일급 시민이기도 합니다.
변수에 함수를 할당하거나, 함수 내부에서 함수를 생성하여 반환하는 등 함수가 해당 언어에서 '일급 객체'처럼 다루어질 때 '일급 함수'라고 표현합니다. 일부에서는 일급 함수가 일급 시민의 조건 이외에도 두 가지 추가 조건을 만족해야 한다고 이야기합니다.
일급 함수의 추가 조건
- 런타임 시 생성이 가능해야 합니다.
- 익명으로 생성이 가능해야 합니다.
자바스크립트의 함수는 위 조건을 모두 만족하므로 일급 객체입니다.
자바스크립트는 "멀티 패러다임 프로그래밍 언어"로 명령형, 함수형, 객체지향 프로그래밍을 지향하는 언어이며, 일급 함수의 개념은 함수형 프로그래밍에서 필수적인 키워드입니다.
일급 객체로 취급되면 무엇이 가능해지나요?링크를 제목에 복사
그렇다면, 함수가 일급 객체로 취급되면 실제로 어떤 것들이 가능해질까요?
-
함수 표현식
함수 선언문과 달리, 함수 표현식은 변수에 함수를 값처럼 할당합니다. 함수 선언문은 호이스팅되지만, 함수 표현식은 변수 선언만 호이스팅되고 초기화는 런타임에 이루어집니다.
// 함수 선언문 — 호이스팅으로 선언 전에도 호출 가능 greet(); // 'Hello' function greet() { console.log('Hello'); } // 함수 표현식 — 선언 전 호출 시 TypeError sayHi(); // TypeError: sayHi is not a function const sayHi = function () { console.log('Hi'); }; -
고차 함수(higher-order function)
함수를 파라미터로 전달받거나 연산의 결과로 반환해주는 함수입니다. 콜백 함수(callback function)를 인자로 받는 경우가 대표적입니다.
함수형 프로그래밍의 핵심으로, 함수에 대한 로직을 감추고 사고를 추상화 수준으로 끌어올릴 수 있습니다. 그래서 추상화의 수준이 높아지는 만큼 생산성도 높아집니다.
아래는 변환 함수를 인자로 받아 배열을 변환하는 고차 함수를 직접 구현한 예시입니다.
function transform(arr, fn) { const result = []; for (const item of arr) { result.push(fn(item)); } return result; } transform([1, 2, 3], (x) => x * 2); // [2, 4, 6] transform([1, 2, 3], (x) => x + '!'); // ['1!', '2!', '3!']이것이 바로
Array.prototype.map이 하는 일입니다. 자바스크립트의 내장 고차 함수로는 다음과 같은 것들이 있습니다.Array.prototype.map,Array.prototype.filter,Array.prototype.reduce,Array.prototype.forEach,Array.prototype.sort,find,findIndex,some,every…함수를 반환하는 고차 함수도 있습니다. 특정 값을 미리 고정해두고 재사용 가능한 함수를 만들 때 유용합니다.
function multiply(factor) { return (number) => number * factor; } const double = multiply(2); const triple = multiply(3); double(5); // 10 triple(5); // 15 -
콜백(callback)
다른 함수의 인자로 전달되어 그 함수 내부에서 호출되는 함수를 콜백 함수라고 합니다. 함수가 일급 객체이기 때문에 가능한 패턴입니다.
const numbers = [1, 2, 3, 4, 5]; const evens = numbers.filter(function (n) { return n % 2 === 0; }); // [2, 4] const doubled = numbers.map((n) => n * 2); // [2, 4, 6, 8, 10]콜백은 동기 맥락(배열 메서드)뿐 아니라 비동기 맥락에서도 널리 쓰입니다.
setTimeout(() => { console.log('1초 후 실행됩니다.'); }, 1000);
정리하면링크를 제목에 복사
자바스크립트에서 함수는 일급 객체입니다. 그래서 함수를 값처럼 변수에 담고, 다른 함수에 넘기고, 함수에서 반환할 수 있습니다. 이 성질 위에 함수 표현식·고차 함수·콜백 패턴이 모두 성립합니다. 결국, 함수형 프로그래밍의 핵심 도구들은 일급 함수라는 단 하나의 조건에서 출발합니다.
관련 글
자바스크립트로 구현하는 힙
힙(Heap) 자료구조의 개념과 Min Heap, Max Heap을 JavaScript와 TypeScript로 구현하는 방법을 정리합니다.
소수 구하기
소수 판별법과 소수를 구하는 알고리즘을 정리합니다.
[프로그래머스 Level 2] 미로 탈출
프로그래머스 미로 탈출을 BFS로 풀이합니다.
모든 글