JavaScript 언어로 코드를 작성하다 보면 함수 선언 방식에 대해 고민하게 됩니다.
현재 함수 선언 방식은 대표적으로 함수 선언문이 있고, 하나는 함수 표현식입니다.
두 개의 차이점을 살펴보도록 하겠습니다.
함수 선언문
함수 선언문은 아래와 같은 형식의 코드 스타일을 가지고 있습니다.
function 함수이름(매개변수) {
// 함수 본문 작성
return 결과;
}
함수 선언문은 다음과 같은 특징을 가지고 있습니다.
- 함수 선언문은 함수 이름이 필수입니다.
- 함수 선언문은 호이스팅을 지원합니다.
console.log(add(1,2)); // 3
function add(a, b) {
return a + b;
}
위와 같이 호이스팅을 지원하기 때문에 아래에 함수를 선언하더라도 위 코드에서 호출해서 사용이 가능합니다.
함수 표현식
함수 표현식은 아래와 같은 형식의 코드 스타일을 가지고 있습니다.
const 변수이름 = function (매개변수) {
return 결과;
};
함수 표현식의 특징은 다음과 같습니다.
- 익명 함수 지원 → 함수 표현식은 이름 없이 선언이 가능합니다.
- 호이스팅 불가 → 호이스팅을 지원하지 않기 때문에 절차지향적으로 처리됩니다.
const subtract = function (a, b) {
return a - b;
};
console.log(subtract(10, 5)); // 5
앞서 말했던 대로 호이스팅이 지원되지 않기 때문에 먼저 함수를 변수에 넣어 선언합니다.
그리고 원하는 곳에서 호출하면 제대로 호출되는 것을 알 수 있습니다. 익명 함수를 지원하지만 변수명에 담는 과정이 있기 때문에 function 뒤에 이름을 선언하지 않아도 활용이 가능합니다.
함수 선언문과 함수 표현식 어떤 차이점이 있나요?
특징 | 함수 선언문 | 함수 표현식 |
---|---|---|
호이스팅 | 스코프 상단으로 호이스팅됨 | 변수만 호이스팅, 함수 본문은 아님 |
이름 | 필수 | 선택(익명 함수 가능) |
선언 방식 | 독립적으로 선언 | 변수에 함수가 할당됨 |
실행 시점 | 선언 전에 호출 가능 | 선언 후에만 호출 가능 |
위와 같은 차이점이 있으며 함수 표현식은 다양한 형태로 선언됩니다.
// 익명 함수
const multiply1 = function (a, b) {
return a * b;
};
// 이름이 있는 함수 표현식
const multiply2 = function multiplyFunction(a, b) {
return a * b;
};
// 화살표 함수
const multiply3 = (x, y) => x * y;
위와 같이 총 세 가지 방법으로 표현될 수 있습니다. 편한 선택 방법으로 활용하면 됩니다.
사용 사례
함수 선언문과 함수 표현식은 각각에 필요한 부분이 존재합니다. 어떨 때 사용하면 좋을지 살펴보겠습니다.
함수 선언문을 사용할 때
함수 선언문을 사용할 때는 앞서 말한 특징을 활용할 때 사용하면 좋습니다. 즉, 호이스팅을 활용하거나 일반적으로 명확한 함수를 정의할 때 사용됩니다.
const result = add(3, 5);
console.log(result); // 8
function add(x, y) {
return x + y;
}
// util 함수 파일
export function multiply(x, y) {
return x * y;
}
위와 같이 호이스팅을 활용하거나 export를 통한 명확한 함수들을 선언할 때 사용하기 좋습니다.
함수 표현식을 사용할 때
함수 표현식을 사용할 때는 콜백 함수를 만들 때 활용합니다. 익명 함수 표현식은 콜백 함수를 만들 때 자주 사용이 됩니다.
setTimeout(function() {
console.log("call function!");
}, 1000);
여기서 말하는 콜백 함수는 파라미터로 일반적인 변수나 값을 전달하는 것이 아닌 함수 자체를 전달하는 것을 말합니다. 그렇기 때문에 콜백 함수는 보통 이름이 존재하지 않는 익명 함수 형태로 전달합니다.
const callback = function print(word) {
console.log(word);
};
function helloFunction(name) {
const words = "안녕 나는 " + name + "이라고 해!";
callback(words);
}
helloFunction('centbin');
위와 같은 형태로 활용됩니다.
결론
함수 선언문과 함수 표현식은 각각의 특징과 적합한 사용 사례가 있습니다. 정리하면 아래와 같습니다.
- 함수 선언문: 코드 구조가 명확해야 하거나, 함수가 스코프 상단에서 호출될 가능성이 있을 때 사용됩니다.
- 함수 표현식: 콜백 함수로 사용할 때 적합합니다.
둘의 차이를 이해하고 상황에 맞게 선택해서 활용하는 것이 좋습니다.
특이사항
자바스크립트의 ES6부터 let과 const 변수 선언 방식이 나왔습니다. 기존에 있던 var 보다 좀 더 안정적이고 강력한 변수 선언 방식으로 등장했습니다. 이때부터 호이스팅에 대해서 부정적인 인식이 보이기 시작합니다. let과 const는 호이스팅을 지원하지 않는다고 표현합니다. 호이스팅은 종종 예기치 않은 동작을 초래하기 때문에 문제가 발생하곤 했습니다.
let과 const의 Temporal Dead Zone(TDZ)에 대해 살펴보면 확실히 이해할 수 있습니다. let과 const도 엄밀히 말하자면 호이스팅을 지원합니다. 즉, let처럼 변수를 선언하면 가장 최상단으로 끌어올릴 수 있습니다. 하지만 TDZ로 인해 let과 const는 참조 오류(ReferenceError)가 발생합니다. 이러한 차이점을 알고 활용하면 좋습니다.