[Day36] Javascript - 함수 선언식과 표현식의 차이

Validator·2023년 8월 3일
0

함수 선언식(Function Declaration)과 함수 표현식(Function Expression)의 차이??

JavaScript에서 함수를 정의하는 방법에는 크게 두 가지 방법이 있다: 함수 선언식(Function Declaration)함수 표현식(Function Expression). 이 두 방식은 각기 특징과 사용 시점에 따라 선택할 수 있다. 함수를 정의하는 여러 가지 방법에 대한 차이와 특징을 알면, 자바스크립트를 좀 더 깊이 있게 이해하고 효율적으로 사용할 수 있다.

1. 함수 선언식(Function Declaration)

함수 선언식은 function 키워드로 시작하며, 이후에 함수의 이름, 매개변수 목록, 그리고 중괄호 {}로 둘러싸인 함수의 본문이 온다.

예시:

function sum(a, b) {
    return a + b;
}

특징

  • 함수 선언식은 호이스팅(Hoisting)의 대상이다. 이 말은 함수 선언 이전에도 함수를 호출할 수 있다는 것을 의미한다. 호이스팅이란 자바스크립트 엔진이 스크립트를 실행하기 전에 스크립트 내의 함수 선언 및 변수 선언을 미리 위쪽으로 끌어올리는 현상을 말한다.
  • 함수 선언식은 전체를 호이스팅하기 때문에 선언 전에 함수를 호출해도 문제 없이 동작한다.

예시:

console.log(sum(1, 2));  // 결과: 3
function sum(a, b) {
    return a + b;
}

2. 함수 표현식(Function Expression)

함수 표현식은 함수를 생성하고 변수에 할당하는 방식으로 정의한다. 이 방식은 function 키워드 다음에 함수 이름이 오지 않고, 바로 매개변수와 함수 본문이 온다. 그리고 이 함수를 변수에 할당한다.

예시:

const sum = function(a, b) {
    return a + b;
};

특징

  • 함수 표현식은 호이스팅의 대상이 아니다. 즉, 함수를 할당하기 전에 호출하려고 하면 TypeError가 발생한다.
  • 함수 표현식은 일급 객체(First-class object)로서의 함수의 특성을 더욱 잘 활용할 수 있다. 예를 들면, 함수를 다른 함수의 인수로 전달하거나, 함수를 반환할 수 있다.

예시:

console.log(sum(1, 2));  // TypeError: sum is not a function

const sum = function(a, b) {
    return a + b;
};

함수 선언식과 함수 표현식의 주요 차이점

  1. 호이스팅(Hoisting)의 영향: 함수 선언식은 호이스팅에 영향을 받아서 함수 선언 전에도 호출이 가능하나, 함수 표현식은 변수의 호이스팅만 영향을 받으므로 함수 할당 전에는 호출할 수 없다.

  2. 익명성: 함수 표현식은 이름이 선택사항이므로 익명 함수(Anonymous function)로 사용될 수 있다. 하지만 함수 선언식은 반드시 이름을 가져야 한다.

  3. 사용 상황: 함수 표현식은 콜백 함수, 즉시 실행 함수(IIFE, Immediately Invoked Function Expression), 클로저(Closure) 등 다양한 고급 패턴에서 주로 사용된다.

호이스팅(Hoisting)이란?

자바스크립트에서는 함수 선언과 변수 선언이 그들이 속한 스코프의 최상단으로 끌어올려진 것처럼 동작하는데, 이 현상을 호이스팅이라고 한다. 하지만 실제로 코드가 물리적으로 이동하는 것은 아니다. 대신, 자바스크립트 엔진이 코드를 해석할 때 선언부를 최상단으로 인식하게 하는 특성을 말한다.

예시:

console.log(a);  // undefined
const a = 5;
console.log(a);  // 5

위 코드에서 var a = 5; 선언 전에 console.log(a);를 실행했음에도 불구하고 에러가 발생하지 않는다. 이는 var a; 선언 부분이 호이스팅되어 스크립트의 최상단에서 실행된 것처럼 동작하기 때문이다.

함수 선언식과 함수 표현식은 각각의 특징과 사용 시점에 따라 적절하게 선택하여 사용할 수 있다. 호이스팅의 개념을 잘 이해하고, 이를 통해 어떤 방식의 함수 정의 방식을 선택할지 판단하는 능력은 자바스크립트를 효과적으로 사용하는 데 중요하다.


함수 표현식의 응용 사례

함수 표현식의 유용성은 다양한 고급 패턴에서 더욱 잘 드러난다. 이번 섹션에서는 그 중 몇 가지 주요한 패턴을 살펴볼 것이다.

1. 즉시 실행 함수 (IIFE: Immediately Invoked Function Expression)

즉시 실행 함수는 함수를 정의함과 동시에 바로 실행되는 함수이다. 이 패턴은 변수의 스코프를 한정하기 위해서 주로 사용되며, 글로벌 스코프에 변수를 추가하지 않아도 되기 때문에 코드의 충돌 없이 구성 요소를 독립적으로 유지할 수 있다.

예시:

(function() {
    const localVar = "I'm a local variable";
    console.log(localVar);
})();

console.log(typeof localVar);  // "undefined"

여기에서 localVar은 IIFE 내부에서만 접근 가능하며, 외부에서는 undefined로 나타난다.

2. 클로저 (Closure)

클로저는 내부 함수가 외부 함수의 맥락에 접근할 수 있는 JavaScript의 특성을 말한다. 이는 내부 함수가 외부 함수의 변수에 접근할 수 있도록 하며, 외부 함수의 실행이 끝난 후에도 변수가 사라지지 않게 한다.

예시:

function outerFunction() {
    const outerVar = "I'm an outer variable";

    function innerFunction() {
        console.log(outerVar);  // "I'm an outer variable"
    }

    return innerFunction;
}

const closure = outerFunction();
closure();

여기에서 innerFunctionouterFunctionouterVar 변수에 접근할 수 있다. outerFunction이 실행을 마쳤음에도 closure()를 통해 outerVar에 접근이 가능하다.

3. 콜백 함수 (Callback Function)

함수 표현식은 종종 이벤트 리스너나 타이머, 비동기 작업 등에 사용되는 콜백 함수로 사용된다. 콜백 함수는 특정 작업이 완료된 후에 실행될 함수를 말한다.

예시:

setTimeout(function() {
    console.log("This will run after 2 seconds");
}, 2000);

setTimeout 함수는 지정된 시간(밀리초) 후에 콜백 함수를 실행한다.

함수 표현식과 익명 함수 (Anonymous Function)

함수 표현식을 사용할 때, 이름을 가지지 않는 함수를 정의하는 경우가 많다. 이러한 함수를 익명 함수라고 한다. 익명 함수는 주로 한 번만 사용될 함수나, 함수의 이름을 별도로 지정할 필요가 없는 곳에 사용된다.

예시:

const multiply = function(a, b) {
    return a * b;
};

여기서 함수는 multiply 변수에 할당되며, 별도의 이름을 가지지 않는다.

함수 표현식의 장점

  1. 유연성: 함수 표현식은 변수, 배열, 객체의 속성 등에 할당될 수 있다. 이러한 특성은 고차 함수 (Higher-order function) 작성 시 유용하다.

  2. 익명성: 이름을 지정할 필요 없이 즉석에서 함수를 생성하고 사용할 수 있다. 이는 코드의 간결성과 유연성을 높여준다.

  3. 코드의 구조화: 즉시 실행 함수와 같은 패턴을 사용하면 코드의 모듈화와 구조화가 용이하다.

함수 선언식과 함수 표현식 중 어느 것을 사용해야 하는 것인가?

두 방식 모두 장점이 있으므로, 상황과 필요에 따라 적절한 방식을 선택하면 된다.

  • 전역 스코프나 함수의 최상단에서 함수를 정의하고, 호이스팅의 특징을 활용하고 싶다면 함수 선언식을 사용한다.
  • 함수를 변수에 할당하거나 다른 함수의 인자로 전달하고 싶다면 함수 표현식을 사용한다.

JavaScript는 다양한 방식으로 함수를 정의하고 사용할 수 있게 해주는 유연한 언어이다. 이러한 다양성은 코드의 표현력을 높여주지만, 동시에 코드의 구조와 작동 방식을 잘 이해하고 사용해야 한다. 함수의 선언과 호출 방식을 올바르게 선택하면, 코드의 가독성과 유지 보수성을 크게 향상시킬 수 있다.

2개의 댓글

comment-user-thumbnail
2023년 8월 3일

좋은 글이네요. 공유해주셔서 감사합니다.

답글 달기
comment-user-thumbnail
2023년 9월 18일

감사합니다.

답글 달기