학습 자료

함수 표현식과 화살표 함수


Article

10강에서 함수를 만들고 불렀다. 이번 강의의 주제는 한 문장으로 요약된다.

자바스크립트에서 함수는 값이다.

숫자를 변수에 담듯 함수를 변수에 담을 수 있고, 숫자를 인자로 넘기듯 함수를 넘길 수 있다. 이 성질이 자바스크립트를 다른 언어와 다르게 만든다.

함수를 변수에 담는다

const greet = function () {
  console.log("안녕하세요");
};

greet();
console.log(typeof greet);
콘솔
  • 안녕하세요
  • 'function'

function 뒤에 이름이 없다. 이름 없는 함수를 만들어 greet이라는 변수에 넣었다. 이걸 함수 표현식이라 부른다. 10강에서 쓰던 방식은 함수 선언문이다.

메모리로 보면 이렇다. 3강에서 본 그림과 같다. 상자에 함수가 들어간 것뿐이다.

변수에 담긴 함수

함수도 객체다. 상자에는 함수가 있는 위치가 적힌다

count
10
greet
0x4f2a
function () { … }

선언문과 표현식의 차이

생김새 말고 실질적인 차이가 하나 있다.

sayHi();
sayHello();

function sayHi() {
  console.log("선언문");
}

const sayHello = function () {
  console.log("표현식");
};
콘솔
  • 선언문
  • ReferenceError: Cannot access 'sayHello' before initialization

선언문은 정의보다 위에서 불러도 동작한다. 표현식은 안 된다.

두 방식

함수 선언문

function name() {}

  • 정의 위에서 호출해도 된다
  • 이름이 필수
  • 어디서든 부를 수 있어 편하다
  • 그래서 순서가 뒤엉키기도 한다

함수 표현식

const name = function () {}

  • 정의 아래에서만 호출할 수 있다
  • 이름을 생략한다
  • const 라 재할당이 막힌다
  • 읽는 순서와 실행 순서가 같다

화살표 함수

ES6에서 더 짧은 문법이 생겼다. function 키워드를 지우고 =>를 넣는다.

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

const addArrow = (a, b) => {
  return a + b;
};

console.log(add(1, 2), addArrow(1, 2));
콘솔
  • 3 3

여기서 더 줄일 수 있다. 규칙이 두 개 있다.

화살표 함수를 줄여가는 과정
  1. 01

    기본 형태

    매개변수 괄호, 중괄호, return 이 모두 있다.

    const double = (n) => {
      return n * 2;
    };
  2. 02

    본문이 return 한 줄이면 중괄호와 return 을 지운다

    남은 식의 결과가 자동으로 반환된다. 이걸 암묵적 반환이라 부른다.

    const double = (n) => n * 2;
  3. 03

    매개변수가 하나면 괄호도 지운다

    0개이거나 2개 이상이면 괄호가 필요하다.

    const double = n => n * 2;
const double = n => n * 2;
const add = (a, b) => a + b;
const hello = () => "안녕";

console.log(double(5), add(1, 2), hello());
콘솔
  • 10 3 '안녕'

객체를 반환할 때 이 규칙이 걸림돌이 된다.

const makeUser = name => { name: name };
console.log(makeUser("지원"));

const makeUserOk = name => ({ name: name });
console.log(makeUserOk("지원"));
콘솔
  • undefined
  • { name: '지원' }

첫 번째는 중괄호를 함수 본문으로 읽어버린다. 객체를 돌려주려면 괄호로 감싸 식이라고 알려줘야 한다.

함수를 인자로 넘긴다 — 콜백

함수가 값이라면, 함수를 다른 함수에 넘길 수도 있다. 넘겨받은 함수를 콜백이라 부른다.

function repeat(count, action) {
  for (let i = 0; i < count; i++) {
    action(i);
  }
}

repeat(3, i => console.log(`${i}번째 실행`));
콘솔
  • 0번째 실행
  • 1번째 실행
  • 2번째 실행

repeat은 "몇 번 반복할지"만 알고, "무엇을 할지"는 모른다. 그건 넘겨받은 함수가 정한다. 반복 로직과 실제 작업이 분리된다.

콜백이 오가는 길
  1. repeat 호출함수를 인자로 넘긴다
  2. repeat 내부언제 부를지 정한다
  3. action(i)넘긴 함수가 실행된다

이 패턴은 앞으로 계속 만난다. 16강의 map, filter도, 버튼 클릭 처리도, 20강의 비동기도 전부 콜백이다.

const numbers = [1, 2, 3];

numbers.forEach(n => console.log(n * 10));
콘솔
  • 10
  • 20
  • 30

화살표 함수가 다른 점

문법만 짧아진 게 아니다. this를 스스로 갖지 않는다.

항목일반 함수화살표 함수
this호출 방식에 따라 정해진다바깥에서 물려받는다
arguments있다없다
new 로 호출가능불가능
문법 길이길다짧다

this가 무엇인지는 19강에서 다룬다. 지금 알아둘 것은 이것뿐이다. 화살표 함수는 일반 함수의 짧은 버전이 아니다. 동작이 다르다.

정리하면

  • 함수는 값이다. 변수에 담고, 인자로 넘기고, 반환할 수 있다.
  • 함수 선언문은 정의 위에서도 호출되지만, 표현식은 안 된다.
  • 화살표 함수는 본문이 한 줄이면 return과 중괄호를 지운다. 객체를 반환하려면 ({ })로 감싼다.
  • 중괄호를 쓰면서 return을 빠뜨리면 **조용히 undefined**가 나온다.
  • 다른 함수에 넘기는 함수를 콜백이라 부른다. 넘길 때 괄호를 붙이지 않는다.
  • 화살표 함수는 this를 갖지 않는다. 짧은 버전이 아니라 다른 함수다.

다음 강의는 스코프다. 3강에서 var가 중괄호를 무시한다고 했던 그 이야기를 이제 제대로 푼다.

함수 표현식과 화살표 함수 — 디코드랩(DCODELAB)