자바스크립트 기본 1.16 함수표현식

Eddy·2023년 5월 22일
0

코어 자바스크립트

목록 보기
16/30

♠ 자바스크립트 기본

♣ 1.16 함수표현식

함수 표현식 vs 함수 선언문

함수 표현식과 선언문의 차이에 대해 알아봅시다.

첫 번째는 문법입니다. 코드를 통해 어떤 차이가 있는지 살펴봅시다.

  • 함수 선언문: 함수는 주요 코드 흐름 중간에 독자적인 구문 형태로 존재합니다.
    // 함수 선언문
    function sum(a, b) {
      return a + b;
    }
  • 함수 표현식: 함수는 표현식이나 구문 구성(syntax construct) 내부에 생성됩니다. 아래 예시에선 함수가 할당 연산자 =를 이용해 만든 “할당 표현식” 우측에 생성되었습니다.
    // 함수 표현식
    let sum = function(a, b) {
      return a + b;
    };

두 번째 차이는 자바스크립트 엔진이 언제 함수를 생성하는지에 있습니다.

함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성합니다. 따라서 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있습니다.

위 예시를 이용해 설명해 보도록 하겠습니다. 스크립트가 실행되고, 실행 흐름이 let sum = function…의 우측(함수 표현식)에 도달 했을때 함수가 생성됩니다. 이때 이후부터 해당 함수를 사용(할당, 호출 등)할 수 있습니다.

하지만 함수 선언문은 조금 다릅니다.

함수 선언문은 함수 선언문이 정의되기 전에도 호출할 수 있습니다.

따라서 전역 함수 선언문은 스크립트 어디에 있느냐에 상관없이 어디에서든 사용할 수 있습니다.

이게 가능한 이유는 자바스크립트의 내부 알고리즘 때문입니다. 자바스크립트는 스크립트를 실행하기 전, 준비단계에서 전역에 선언된 함수 선언문을 찾고, 해당 함수를 생성합니다. 스크립트가 진짜 실행되기 전 "초기화 단계"에서 함수 선언 방식으로 정의한 함수가 생성되는 것이죠.

스크립트는 함수 선언문이 모두 처리된 이후에서야 실행됩니다. 따라서 스크립트 어디서든 함수 선언문으로 선언한 함수에 접근할 수 있는 것입니다.

eddy’s point

스코프

엄격 모드에서 함수 선언문이 코드 블록 내에 위치하면 해당 함수는 블록 내 어디서든 접근할 수 있습니다. 하지만 블록 밖에서는 함수에 접근하지 못합니다.

예시를 들어 설명해 보겠습니다. 런타임에 그 값을 알 수 있는 변수 age가 있고, 이 변수의 값에 따라 함수 welcome()을 다르게 정의해야 하는 상황입니다. 그리고 함수 welcome()은 나중에 사용해야 하는 상황이라고 가정해 보죠.

함수 선언문을 사용하면 의도한 대로 코드가 동작하지 않습니다.

    let age = prompt("나이를 알려주세요.", 18);
    
    // 조건에 따라 함수를 선언함
    if (age < 18) {
    
      function welcome() {
        alert("안녕!");
      }
    
    } else {
    
      function welcome() {
        alert("안녕하세요!");
      }
    
    }
    
    // 함수를 나중에 호출합니다.
    *welcome(); // Error: welcome is not defined*

함수 선언문은 함수가 선언된 코드 블록 안에서만 유효하기 때문에 이런 에러가 발생합니다.

또 다른 예시를 살펴봅시다.

    let age = 16; // 16을 저장했다 가정합시다.
    
    if (age < 18) {
      *welcome();               // \   (실행)*//  |
      function welcome() {     //  |
        alert("안녕!");        //  |  함수 선언문은 함수가 선언된 블록 내
      }                        //  |  어디에서든 유효합니다
                               //  |
      *welcome();               // /   (실행)*} else {
    
      function welcome() {
        alert("안녕하세요!");
      }
    }
    
    // 여기는 중괄호 밖이기 때문에
    // 중괄호 안에서 선언한 함수 선언문은 호출할 수 없습니다.
    
    *welcome(); // Error: welcome is not defined*

그럼 if문 밖에서 welcome 함수를 호출할 방법은 없는 걸까요?

함수 표현식을 사용하면 가능합니다. if문 밖에 선언한 변수 welcome에 함수 표현식으로 만든 함수를 할당하면 되죠.

이제 코드가 의도한 대로 동작합니다.

    let age = prompt("나이를 알려주세요.", 18);
    
    let welcome;
    
    if (age < 18) {
    
      welcome = function() {
        alert("안녕!");
      };
    
    } else {
    
      welcome = function() {
        alert("안녕하세요!");
      };
    
    }
    
    *welcome(); // 제대로 동작합니다.*

물음표 연산자 ?를 사용하면 위 코드를 좀 더 단순화할 수 있습니다.

    let age = prompt("나이를 알려주세요.", 18);
    
    let welcome = (age < 18) ?
      function() { alert("안녕!"); } :
      function() { alert("안녕하세요!"); };
    
    *welcome(); // 제대로 동작합니다.*

0개의 댓글