This page was translated from English by the community. Learn more and join the MDN Web Docs community.

View in English Always switch to English

화살표 함수 표현식

Baseline
Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2016년 9월.

화살표 함수 표현식(화살표 함수 expression)은 함수 표현식에 대한 간결한 대안으로, 약간의 의미적 차이와 의도적인 사용상의 제한을 가지고 있습니다.

  • 화살표 함수에는 자체 바인딩this에 없으며, 인수 또는 super로 사용해야 하며, 메서드로 사용하면 안 됩니다.
  • 화살표 함수는 생성자로 사용할 수 없습니다. new로 호출하면 TypeError가 반환됩니다. new.target 키워드에 대한 액세스 권한도 없습니다.
  • 화살표 함수는 함수 내부에서 yield를 사용할 수 없으며 제너레이터 함수로 생성할 수 없습니다.

시도해 보기

const materials = ["Hydrogen", "Helium", "Lithium", "Beryllium"];

console.log(materials.map((material) => material.length));
// Expected output: Array [8, 6, 7, 9]

구문

js
() => expression

param => expression

(param) => expression

(param1, paramN) => expression

() => {
  statements
}

param => {
  statements
}

(param1, paramN) => {
  statements
}

매개변수 내 나머지 매개변수, 기본값 매개변수, 구조 분해 할당이 지원되며 항상 괄호 안에 넣어야 합니다.

js
(a, b, ...r) => expression
(a = 400, b = 20, c) => expression
([a, b] = [10, 20]) => expression
({ a, b } = { a: 10, b: 20 }) => expression

화살표 함수는 표현식 앞에 async 키워드를 붙여서 async로 지정할 수 있습니다.

js
async param => expression
async (param1, param2, ...paramN) => {
  statements
}

설명

기존의 익명 함수를 가장 간단한 화살표 함수로 단계별로 분해해 보겠습니다. 이 과정에서 각 단계는 유효한 화살표 함수입니다.

참고 : 기존 함수 표현식과 화살표 함수는 구문 외에도 더 많은 차이점이 있습니다. 다음 몇 개의 하위 섹션에서 두 함수의 동작 차이에 대해 자세히 소개하겠습니다.

js
// 기존의 익명 함수
(function (a) {
  return a + 100;
});

// 1. "function"이라는 단어를 제거하고 인자와 여는 대괄호 사이에 화살표를 배치합니다.
(a) => {
  return a + 100;
};

// 2. 중괄호와 "return"이라는 단어를 제거하면 반환이 암시됩니다.
(a) => a + 100;

// 3. 매개변수의 괄호를 제거합니다.
a => a + 100;

위의 예에서는 매개변수 주위의 괄호와 함수 본문 주위의 중괄호를 모두 생략할 수 있습니다. 그러나 특정 경우에만 생략할 수 있습니다.

괄호는 함수에 하나의 간단한 매개변수가 있는 경우에만 생략할 수 있습니다. 매개 변수가 여러 개 있거나 없거나 기본값인 경우와 구조 분해 할당된 매개 변수 또는 나머지 매개 변수가 있는 경우 매개 변수 목록 주위에 괄호를 사용해야 합니다.

js
// 기존의 익명 함수
(function (a, b) {
  return a + b + 100;
});

// 화살표 함수
(a, b) => a + b + 100;

const a = 4;
const b = 2;

// 기존의 익명 함수 (매개변수가 없음)
(function () {
  return a + b + 100;
});

// 화살표 함수 (매개변수가 없음)
() => a + b + 100;

중괄호는 함수가 직접 표현식을 반환하는 경우에만 생략할 수 있습니다. 본문에 추가로 처리하는 구문이 있는 경우 중괄호가 필요하며 return 키워드도 마찬가지입니다. 화살표 함수는 무엇을 언제 반환할지 추측할 수 없습니다.

js
// 기존의 익명 함수
(function (a, b) {
  const chuck = 42;
  return a + b + chuck;
});

// 화살표 함수
(a, b) => {
  const chuck = 42;
  return a + b + chuck;
};

화살표 함수는 항상 이름이 지정되지 않습니다. 화살표 함수가 스스로를 호출해야 하는 경우 명명된 함수 표현식을 대신 사용하세요. 화살표 함수를 변수에 할당하여 이름을 지정할 수도 있습니다.

js
// 기존 함수
function bob(a) {
  return a + 100;
}

// 화살표 함수
const bob2 = (a) => a + 100;

함수 내부

화살표 함수는 간결한 본문이나 일반적인 블록 형태의 본문을 가질 수 있습니다.

간결한 본문에서는 암시적 반환값이 되는 단일 표현식만 지정됩니다. 블록 본문에서는 명시적인 return 문을 사용해야 합니다.

js
const func = (x) => x * x;
// 간결한 본문 구문, 암시적 "반환"

const func2 = (x, y) => {
  return x + y;
};
// 블록 본문을 포함, 명시적 "반환" 필요

간결한 본문 구문은 (params) => { object: literal }을 사용하여 객체 리터럴을 반환하면 예상대로 작동하지 않습니다.

js
const func = () => { foo: 1 };
// func()를 호출하면 정의되지 않은 값이 반환됩니다.

const func2 = () => { foo: function () {} };
// SyntaxError: function statement requires a name

const func3 = () => { foo() {} };
// SyntaxError: Unexpected token '{'

JavaScript는 화살표 뒤에 오는 토큰이 왼쪽 중괄호가 아닌 경우에만 화살표 함수에 간결한 본문이 있는 것으로 간주합니다. 중괄호({}) 안의 코드는 일련의 구문으로 파싱되며, 여기서 foo는 객체 리터럴의 키가 아닌 label이 됩니다.

이 문제를 해결하려면 객체 리터럴을 괄호로 묶으면 됩니다.

js
const func = () => ({ foo: 1 });

메서드로 사용할 수 없습니다

화살표 함수 표현식은 this가 없기 때문에 메서드가 아닌 함수에만 사용해야 합니다. 메서드로 사용하려고 하면 어떤 일이 일어나는지 살펴봅시다.

js
"use strict";

const obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c() {
    console.log(this.i, this);
  },
};

obj.b(); // logs undefined, Window { /* … */ } (or the global object)
obj.c(); // logs 10, Object { /* … */ }

또 다른 예는 Object.defineProperty()와 관련된 것입니다.

js
"use strict";

const obj = {
  a: 10,
};

Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window { /* … */ } (or the global object)
    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
  },
});

클래스의 내부에는 this가 있으므로, 화살표 함수는 클래스 필드가 클래스의 this 컨텍스트 위에 닫힐 때 작동합니다. 그러면 화살표 함수 내부의 this가 인스턴스 (또는 정적 필드의 경우 클래스 자체)를 올바르게 가리키게 됩니다. 그러나 함수 자체의 바인딩이 아닌 클로저이므로 실행 컨텍스트에 따라 this의 값이 변경되지 않습니다.

js
class C {
  a = 1;
  autoBoundMethod = () => {
    console.log(this.a);
  };
}

const c = new C();
c.autoBoundMethod(); // 1
const { autoBoundMethod } = c;
autoBoundMethod(); // 1
// 정상적인 메서드라면 이 경우에는 정의되지 않아야 합니다.

화살표 함수 속성은 일반 메서드와 동일하기 때문에 흔히 "자동 바인딩 메서드"라고 불립니다.

js
class C {
  a = 1;
  constructor() {
    this.method = this.method.bind(this);
  }
  method() {
    console.log(this.a);
  }
}

참고 : 클래스 필드는 프로토타입이 아닌 인스턴스에 정의되므로 인스턴스를 생성할 때마다 새 함수 참조가 생성되고 새 클로저가 할당되어 일반적인 언바운드 메서드보다 메모리 사용량이 늘어날 수 있습니다.

비슷한 이유로 call(), apply(), bind() 메서드는 화살표 함수에서 호출할 때 유용하지 않습니다. 화살표 함수는 화살표 함수가 정의된 범위를 기반으로 this을 설정하고 함수가 호출되는 방식에 따라 this 값이 변하지 않기 때문입니다.

인수의 바인딩이 없습니다

화살표 함수에는 자체 arguments 객체가 없습니다. 따라서 이 예제에서 arguments는 둘러싸는 범위의 인수를 참조합니다.

js
function foo(n) {
  const f = () => arguments[0] + n; // foo의 암시적 인자 바인딩입니다. arguments[0]은 n입니다.
  return f();
}

foo(3); // 3 + 3 = 6