자바스크립트에는 퍼스트 클래스(first class)가 있다는 사실을 알고 계십니까. 퍼스트 클래스하면 무엇이 제일 먼저 떠오르시나요? '비싸고', '편하고', '일부만 해당하고' 등 다양한 특징들을 떠올려 볼 수 있습니다. 그리고 이런 점들을 일반화해서 '특별한 대우를 받는다'고 해도 크게 틀리지 않습니다.
자바스크립트의 세계에서도 특별한 대우를 받는 것들이 있습니다. 이런 것들을 일급 객체(first-class citizen)라고 합니다. 그 중 하나가 함수(function)입니다. 즉 자바스크립트에서 함수는 (자바스크립트가 나온 시점을 고려했을 때) 아래와 같이 특별하게 취급됩니다.
이는 함수를 데이터(string
, number
, boolean
, array
, object
)를 다루듯이 다룰 수 있다는 걸 의미합니다. 변수에 저장할 수 있기 때문에 배열의 요소나 객체의 속성값으로 저장하는 것도 가능합니다.
우리는 이미 함수를 변수에 저장하는 방법을 배웠습니다. 바로 함수 표현식(function expression) 입니다. 아래의 함수 표현식은 함수 선언식(function declaration)과 다르게 호이스팅(hoisting)이 적용되지 않습니다.
변수에 함수를 할당하는 경우
// 아래는 변수 square에 함수를 할당하는 함수 표현식입니다.
// 자바스크립트에서 함수는 일급 객체이기 때문에 변수에 저장할 수 있습니다.
// 함수 표현식은 할당 전에 사용할 수 없습니다.
// square(7); // --> ReferenceError: Can't find variable: square
const square = function (num) {
return num * num;
};
// square에는 함수가 저장되어 있으므로 (일급 객체), 함수 호출 연산자 '()'를 사용할 수 있습니다.
output = square(7);
console.log(output); // --> 49
함수 선언식의 호이스팅에 지나치게 의존하는 것은 코드의 유지 보수 측면에서 좋지 않습니다. 코드 리뷰나 디버깅을 할 때 코드를 위 아래로 왔다 갔다하게 될 수 있습니다. 함수 선언식의 경우, 어느 위치에나 함수를 선언할 수 있고 함수의 실행 위치도 중요하지 않기 때문입니다. 반면, 함수 표현식은 함수의 할당과 실행의 위치가 중요하기 때문에 코드의 위치가 어느 정도 예측 가능합니다.
호이스팅을 제외하면 함수 선언식과 함수 표현식의 차이는 크게 없어 보이고, 실제로도 그렇습니다. 다만 함수 표현식의 경우, 함수가 변수에 저장될 수 있다는 사실을 좀 더 분명하게 드러낼 수 있습니다.
한편, 변수에 저장된 데이터는 함수의 인자로 전달되거나 함수 내에서 리턴값으로 사용될 수 있습니다. 앞서 함수가 변수에 저장될 수 있다는 사실로부터, 함수 역시 다른 함수의 인자로 전달되거나 다른 함수 내에서 리턴될 수 있다는 것을 알 수 있습니다.