[모던 자바스크립트 튜토리얼] 2.16 함수 표현식

개발견 배도르만·2023년 3월 2일
0
post-thumbnail

함수 표현식

자바스크립트에서는 함수를 대하는 방식이 다른 언어와 조금 다르다. 특별한 동작을 하는 구조가 아닌 특별한 종류의 으로 취급한다.
일반적으로는 함수 선언, 함수 선언문 방식으로 함수를 만든다.

function sayHi() {
  alert( "Hello" );
}

외에도 함수 표현식(Function Expression)으로 함수를 만들 수 있다.

let sayHi = function() {
  alert( "Hello" );
};

함수를 생성하고 변수에 함수를 할당하는 개념이다. 함수가 어떤 방식으로 만들어졌는지에 관계없이 함수는 값이기에, 변수에 할당할 수 있다.

function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // 함수 코드가 보임

sayHi 함수가 실행되지 않고 코드만 보이는 이유는 호출 시 괄호를 붙이지 않아서이다. 특정 언어에서는 함수 이름만 언급해도 함수가 실행되지만 자바스크립트는 괄호가 있어야만 함수가 호출된다.
함수를 값으로 취급할 수 있기 때문이다. '기능'이 있는 특별한 값이라고 생각하면 될 것 같다.
그리고 값이기 때문에 값에 할 수 있는 일을 함수에도 할 수 있다.

function sayHi() {   // (1) 함수 생성
  alert( "Hello" );
}

let func = sayHi;    // (2) 함수 복사

func(); // Hello     // (3) 복사한 함수를 실행(정상적으로 실행됨)!
sayHi(); // Hello    //     본래 함수도 정상적으로 실행됨

/*-------------표현식으로 정의하여 복사하는 경우---------------*/
let sayHi = function() {
  alert( "Hello" );
};

let func = sayHi;

// 두 방법의 동작 결과는 동일

위 두 방식의 미묘한 차이가 있다면 세미콜론의 유무이다. if(){}, for(){}, function f(){} 등의 코드 블럭(중괄호로 코드를 묶은 것) 끝엔 세미콜론이 없어도 된다. 하지만 함수 표현식은 let sayHi = ...;과 같은 구문 안에서 코드 블럭이 아닌 값처럼 취급되어 변수에 할당된다. 모든 구문의 끝엔 세미콜론을 붙이는 것이 좋다는 전제 하에, 함수 표현식 뒤의 세미콜론은 함수 표현식 때문에 붙여진 것이 아니라 구문의 끝이기에 붙여진 것이다.

콜백함수

콜백함수(Callback function)는 매개변수를 함수로 받아 나중에 호출하는 함수이다.

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

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

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

// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);

위 예시는
1) ask 함수 실행 시 confirm 창에 question 문구를 표시하고
2-1) 사용자가 확인 버튼을 누르면 yes 함수를,
2-2) 취소를 누르면 no 함수를 실행시킨다.
3) 하단의 코드에서 ask 함수 호출 시 동의 메세지, showOk, showCancel의 세 인자를 넣었다.
4) 따라서 사용자의 버튼 클릭에 따라 showOk 또는 showCancel 함수가 실행될 것이다.
5) 이 때 showOk, showCancel 함수가 콜백 함수 또는 콜백이라고 불린다.

익명 함수를 함수 내에서만 사용하게 할 수도 있다.

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

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

ask 함수 호출 시 인자 세 개중 두 개가 함수인데 함수명이 없다. 이렇게 이름 없이 선언한 함수를 익명함수(anonymous function)라고 한다. 익명 함수는 변수에 할당된 것이 아니기에 선언 시에 호출한 함수 외에서는 접근할 수 없다(느낌 상 제한이라기보다는 접근할 방법이 없겠다...).

함수 표현식 vs 함수 선언문

표현식과 선언문의 차이

1) 문법

  • 함수 선언문 : 주요 코드 흐름 중간에 독자적인 구문 형태로 존재
  • 함수 표현식 : 표현식이나 구문 구석 내부에 생성

2) 엔진에서의 함수 생성 시점

  • 함수 선언문 : 스크립트 실행 전
  • 함수 표현식 : 실행 흐름이 function... 에 도달 시
    -> 따라서 함수 선언문은 스크립트 어디서든 사용 가능, 표현식은 해당 표현식 이후 코드에서부터 사용 가능

3) 스코프(범위)
엄격모드에서

  • 함수 선언문 : 코드 블록(if, for, function 등 특정 구문의 중괄호) 내에서 선언 시 마찬가지로 생성 시점이 이르기 때문에 블록 내 어디서든 접근 가능하지만 해당 블록 밖에서는 접근 불가
  • 함수 표현식 : 코드 블록 내에서 작성된 함수 표현식이더라도 할당하는 변수가 해당 블럭 밖에 위치하면 함수 할당 및 블럭 외부에서 접근 가능

경우에 따라 선택해야 하겠지만 우선적으로 함수 선언문을 고려하는 것이 권장된다. 선언 이전에 호출이 가능하기도 하고, let 등으로 시작하는 코드보다는 function으로 시작하는 코드가 더 눈에 띄게 함수 같아 보이기 때문이다.

✍️ 정리

  • 함수 ⊂ 값
  • 함수 선언(문) 방식으로 함수 생성 시, 함수가 독립적인 구문 형태로 존재
  • 함수 표현식 방식으로 함수 생성 시, 함수가 표현식의 일부로 존재
  • 함수 선언문은 코드 블록 실행되기 전에 처리 -> 블록 내 어디서든 활용 가능
  • 함수 표현식은 실행 흐름이 표현식을 만나야 생성됨
  • 함수 선언문 vs 함수 표현식 -> 함수 선언문이 생성 시점과 가독성에 있어서 유리한 면이 있음
  • 함수 선언문이 부적합할 경우에 함수 표현식을 사용하면 좋음
profile
네 발 개발 개

0개의 댓글