Posts 모던 자바스크립트 #2.16. 함수 표현식
Post
Cancel

모던 자바스크립트 #2.16. 함수 표현식

모던 JavaScript 튜토리얼을 따라가면서 정리합니다.

2.16. 함수 표현식(Function Expression)

  • 자바스크립트에서 함수는 값이다. 다른 언어처럼 특별한 동작을 하는 구조로 취급되지 않는다. 다만 호출할 수 있다는 점 때문에 일반적인 값과 다른 특별한 종류의 값이다.

  • 함수를 생성하고 변수에 값을 할당하는 것처럼 함수가 변수에 할당되었다.

  • 괄호가 있어야만 함수가 호출된다. 괄호 없이 함수 이름만 언급하면 함수 소스 코드가 문자형으로 바뀌어 출력된다.

    1
    2
    3
    4
    5
    
    function sayHi() {
      alert( "Hello" );
    }
      
    alert( sayHi ); // 함수 코드가 보임
    
  • 변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당할 수도 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    
    function sayHi() {   // (1) 함수 생성
      alert( "Hello" );
    }
      
    let func = sayHi;    // (2) 함수 복사
      
    func(); // Hello     // (3) 복사한 함수를 실행(정상적으로 실행됩니다)!
    sayHi(); // Hello    //     본래 함수도 정상적으로 실행됩니다.
    
  • 함수 표현식은 let sayHi = ...;과 같은 구문 안에서 값의 역할을 한다. 따라서 함수표현식 끝에는 함수 선언문과 달리 세미콜론이 붙는다.

콜백 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert("동의하셨습니다.");
}

function showCancel() {
  alert("취소 버튼을 누르셨습니다.");
}

ask("동의하십니까?", showOk, showCancel);

함수 ask의 인수, showOkshowCancel콜백 함수 또는 콜백이라고 불린다. 함수를 함수의 인수로 전달하고, 필요하면 그 함수를 나중에 호출(call back)하는 것이다.

1
2
3
4
5
6
7
8
9
10
function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "동의하십니까?",
  function() { alert("동의하셨습니다."); },
  function() { alsert("취소 버튼을 누르셨습니다."); }
);

위와 같이 익명 함수(anonymous function)을 파라미터로 전달할 수도 있다. 자바스크립트를 사용하다 보면 콜백을 활용한 코드를 아주 자연스럽게 만나게 된다. 이런 코드는 자바스크립트의 정신을 대변한다.

함수는 “동작”을 나타내는 값이다. 문자열이나 숫자 등 일반적인 값들은 데이터를 나타낸다. 함수는 하나의 동작(action)을 나타낸다. 동작을 대변하는 값인 함수를 변수 간 전달하고, 동작이 필요할 때 이 값을 실행할 수 있다.

함수 표현식 vs 함수 선언문

존재 방식

“함수 선언(문)” 방식으로 함수를 생성하면, 함수가 독립된 구문 형태로 존재하게 됩니다. “함수 표현식” 방식으로 함수를 생성하면, 함수가 표현식의 일부로 존재하게 된다.

함수 생성 시점

함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성한다. 따라서 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다. 그러나 함수 선언문함수 선언문이 정의되기도 전에 호출할 수 있다. 자바스크립트는 스크립트를 실행하기 전, 준비 단계에서 전역에 선언된 함수 선언문을 찾고, 해당 함수를 생성한다. 스크립트는 함수 선언문이 모두 처리된 이후에서야 실행된다. 따라서 스크립트 어디서든 함수 선언문으로 선언한 함수에 접근할 수 있는 것이다.

스코프

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

런타임에 그 값을 알 수 있는 변수 age가 있고, 이 변수의 값에 따라 welcome()을 다르게 정의해야 하는 상황이다. 그리고 함수 welcome은 나중에 사용해야 하는 상황이라 가정해보자. 함수 선언문을 사용하면 의도한 대로 코드가 동작하지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let age = prompt("나이를 알려주세요.", 18);

// 조건에 따라 함수를 선언함
if (age < 18) {
  function welcome() {
    alert("안녕!");
  }
} else {
  function welcome() {
    alert("안녕하세요!");
  }
}

welcome(); // Error: welcome is not defined

if문 밖에 welcome 함수를 호출하려면 함수 표현식을 사용해야 한다. if문 밖에 선언한 변수 welcome에 함수 표현식으로 만든 함수를 할당하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let age = prompt("나이를 알려주세요.", 18);

let welcome;

if (age < 18) {

  welcome = function() {
    alert("안녕!");
  };

} else {

  welcome = function() {
    alert("안녕하세요!");
  };

}

welcome(); // 제대로 동작합니다.

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

1
2
3
4
5
6
7
let age = prompt("나이를 알려주세요.", 18);

let welcome = (age < 18) ?
  function() { alert("안녕!"); } :
  function() { alert("안녕하세요!"); };

welcome(); // 제대로 동작합니다.

함수 선언문을 이용해 함수를 선언하는 것을 먼저 고려하는 것이 좋다. 함수가 선언되기 전에 호출할 수 있어서 코드 구성을 좀 더 자유롭게 할 수 있기 때문이다. 또한 가독성도 좋다. 함수 표현식은 함수 선언문을 사용하는 것이 부적절할 때에 사용하는 것이 좋다.

This post is licensed under CC BY 4.0 by the author.

모던 자바스크립트 #2.15. 함수

스프링 입문 #3 회원관리 예제: 백엔드 개발

Loading comments from Disqus ...