반응형
자바스크립트를 배우다 보면 함수를 정의하는 방식에 따라 동작이 다르다는 점을 접하게 됩니다. 그 중 대표적인 것이 함수 선언식과 함수 표현식입니다. 이 두 가지는 겉보기에는 유사해 보이지만, 호이스팅, 스코프, 실행 시점, 디버깅 편의성, 조건부 선언 등 다양한 면에서 중요한 차이를 지닙니다.
이번 글에서는 이 두 방식의 차이를 정확히 이해하고, 실제 개발에 어떻게 적용하면 좋을지를 보다 심도 있게 다뤄보겠습니다.
✅ 함수 선언식 (Function Declaration)
function greet() {
console.log("Hello!");
}
📌 개념 및 특징
- 이름을 가진 함수 정의 방식
- 전체 코드에서 참조 가능 (호이스팅에 의해)
- 스코프는 함수 레벨 스코프를 따름
- strict mode에서도 안정적으로 동작
- 전통적인 자바스크립트 환경에서 널리 사용됨
📌 호이스팅 원리
- 함수 전체가 컴파일 타임에 메모리에 등록됨
- 따라서 코드의 어떤 위치에서든 선언 이전에 접근 가능
✅ 예시
sayHello(); // 정상 출력
function sayHello() {
console.log("안녕하세요!");
}
📌 장점
- 함수 호출이 코드 위쪽에서도 가능하므로 유틸리티 함수 구성에 용이
- 명확한 이름과 선언 위치로 인해 가독성이 좋음
📌 단점
- 조건문 내에서 선언할 경우 브라우저마다 해석이 달라질 수 있음 (비표준)
✅ 함수 표현식 (Function Expression)
const greet = function() {
console.log("Hello!");
};
📌 개념 및 특징
- 변수에 할당된 익명 또는 기명 함수
- 변수 선언만 호이스팅되고, 함수는 런타임에 메모리에 할당됨
- 스코프는 블록 스코프 (let, const) 또는 **함수 스코프 (var)**를 따름
📌 실행 시점 차이
- 선언 이후에만 호출 가능
- 익명 함수를 활용한 콜백 또는 동적 함수 구성이 유리함
✅ 예시
greet(); // TypeError: greet is not a function
const greet = function() {
console.log("안녕하세요!");
};
📌 장점
- 동적 함수 생성이나 클로저 구성에 유용
- 조건부로 함수 정의할 수 있어 유연함
📌 단점
- 선언 이전 호출 불가
- 익명 함수는 디버깅 시 추적 어려움 (이름 없는 경우)
✅ 이름 있는 함수 표현식 (Named Function Expression)
const greet = function hello() {
console.log("Hello!");
};
📌 특징
- 외부에서는 greet로 접근
- 내부에서 재귀 호출 시 hello() 사용 가능
- 디버깅 시 스택 트레이스에 함수 이름이 출력되어 추적이 용이함
✅ 예시 (재귀 호출)
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1);
};
✅ 차이 정리 (비교 표)
항목 |
함수 선언식 | 함수 표현식 |
이름 | 필수 | 선택적(익명 가능) |
호이스팅 | 전체 함수가 호이스팅 | 변수 선언만 호이스팅 |
선언 이전 호출 | 가능 | 불가능 (런타임 오류) |
사용 위치 | 전역, 유틸 함수 | 콜백, 조건부, 동적 선언 |
디버깅 편의성 | 낮음 (익명) | 높음 (이름 있는 표현식) |
조건부 정의 | 비표준 (사용 지양) | 안전하고 표준적 |
✅ 조건부 함수 정의의 주의점
❌ 함수 선언식 사용 시 예측 불가 동작
if (true) {
function test() {
console.log("실행됨");
}
}
test(); // 브라우저마다 결과 다름 (비표준)
✅ 함수 표현식 사용 권장
let test;
if (true) {
test = function() {
console.log("안전하게 실행됨");
};
}
test(); // 안전하게 실행
✅ 즉시 실행 함수 (IIFE: Immediately Invoked Function Expression)
함수 표현식에서만 가능한 패턴으로, 함수 정의 직후 바로 실행할 수 있습니다.
(function() {
console.log("즉시 실행!");
})();
📌 사용 이유
- 초기화 코드 한 번만 실행
- 클로저 영역 확보
- 전역 변수 오염 방지
📌 고급 응용 예시: 모듈화 구현
const counter = (function() {
let count = 0;
return {
increment() {
count++;
return count;
},
get() {
return count;
}
};
})();
console.log(counter.increment()); // 1
console.log(counter.get()); // 1
✅ 화살표 함수와 함수 표현식의 관계
화살표 함수도 함수 표현식의 한 형태입니다. 문맥상 동일한 제한을 가집니다.
const greet = () => {
console.log("안녕!");
};
- 선언 이전 호출 불가
- this 바인딩이 없음
- 간결한 문법과 콜백 함수에서 유리함
✅ 실무 활용 팁
상황 | 권장 방식 |
전역 유틸 함수 | 함수 선언식 |
콜백 함수, 이벤트 핸들러 | 함수 표현식 / 화살표 함수 |
클로저 사용, 조건부 선언 | 함수 표현식 |
디버깅 용이성 필요 | 이름 있는 함수 표현식 |
모듈화된 초기화 | IIFE 표현식 |
✅ 결론
함수 선언식과 함수 표현식은 단지 문법 구조의 차이를 넘어 실행 흐름, 스코프 범위, 호이스팅 처리, 디버깅 전략, 모듈 구성에 이르기까지 자바스크립트의 기본 동작 방식에 큰 영향을 미치는 중요한 개념입니다.
실전 개발에서는 가독성, 디버깅, 조건부 제어, 코드 유지보수성을 고려하여 적절한 함수를 선택하는 것이 필수입니다. 단순히 작동하는 코드를 넘어서, 동작 원리를 정확히 이해하고 있는 개발자가 되는 것이 중요합니다.
반응형
'Programing > javascript' 카테고리의 다른 글
힙 정렬 (Heap Sort) 설명과 JavaScript 예제 (0) | 2025.05.22 |
---|---|
JavaScript 비교 연산자 (1) | 2025.05.18 |
JavaScript 조건문 (0) | 2025.05.18 |
JavaScript 반복문 (0) | 2025.05.18 |
함정에 빠지기 쉬운 자바스크립트 문법12 (0) | 2025.05.05 |
함정에 빠지기 쉬운 자바스크립트 문법11 (1) | 2025.05.05 |
함정에 빠지기 쉬운 자바스크립트 문법10 (0) | 2025.05.05 |
함정에 빠지기 쉬운 자바스크립트 문법9 (0) | 2025.05.05 |