화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적당합니다. 그래서 생성자로서 사용할 수 없습니다. 

구문

기본 구문

(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
          // 다음과 동일함:  => { return expression; }

// 매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요:
() => { statements }

 

고급 구문

// 객체 리터럴 식을 반환하는 본문(body)을 괄호 속에 넣음:
params => ({foo: bar})

// 나머지 매개변수기본 매개변수가 지원됨
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

// 매개변수 목록 내 비구조화도 지원됨
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  // 6

상세한 구문 예는 여기에서 볼 수 있습니다.

설명

Hacks 블로그 "ES6 In Depth: Arrow functions" 포스트 참조.

화살표 함수 도입에 영향을 준 두 요소: 짧은 함수 및  바인딩하지 않은 this.

짧은 함수

일부 함수 패턴에서는, 짧은 함수가 환영받습니다. 비교해 보세요:

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );

바인딩 되지 않은 this

화살표 함수전까지는, 모든 새로운 함수는 자신의 this 값을 정의했습니다 (이 함수가 생성자인 경우는 새로운 객체, 엄격 모드 함수 호출에서는 undefined, 함수가 "객체 메서드"로서 호출된 경우 문맥 객체 등) . 이는 객체 지향 스타일 프로그래밍에 성가신 일임이 드러났습니다.

function Person() {
  // Person() 생성자는 `this`를 자신의 인스턴스로 정의.
  this.age = 0;

  setInterval(function growUp() {
    // 비엄격 모드에서, growUp() 함수는 `this`를
    // 전역 객체로 정의하고, 이는 Person() 생성자에
    // 정의된 `this`와 다름.
    this.age++;
  }, 1000);
}

var p = new Person();

ECMAScript 3/5 에서는, 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

function Person() {
  var that = this;  
  that.age = 0;

  setInterval(function growUp() {
    // 콜백은  `that` 변수를 참조하고 이갓은 값이 기대한 객체이다.
    that.age++;
  }, 1000);
}

이렇게 하는 대신에, 바인딩한 함수는 적절한 this 값이 growUp() 함수에 전달될 수 있도록 생성될 수 있습니다.

화살표 함수는 자신만의 this를 생성하지 않습니다. this는 감싸고 있는 컨텍스트로 부터 원래의 의미를 갖습니다. 그래서 다음 코드는 기대한대로 작동합니다.

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 는 정확히 person 객체를 참조
  }, 1000);
}

var p = new Person();

엄격 모드와의 관계

this가 렉시컬(lexical, 정적)임을 감안하면, this에 관한 엄격 모드 규칙은 그냥 무시됩니다.

var f = () => {'use strict'; return this};
f() === window; // 또는 전역 객체

엄격 모드의 나머지 규칙은 평소대로 적용합니다.

call 또는 apply를 통한 피호출

화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는  인자만 전달 할 수 있습니다. this는 무시됩니다.

var adder = {
  base : 1,
    
  add : function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };
            
    return f.call(b, a);
  }
};

console.log(adder.add(1));         // 이는 2가 콘솔에 출력될 것임
console.log(adder.addThruCall(1)); // 이도 2가 콘솔에 출력될 것임

바인딩 되지 않은 arguments

화살표 함수는 arguments 객체를 바인드 하지 않습니다.  때문에, arguments는  그저 둘러싸는 범위(scope) 내 이름에 대한 참조입니다.

var arguments = 42;
var arr = () => arguments;

arr(); // 42

function foo() {
  var f = (i) => arguments[0]+i; // foo 함수의 암시된 arguments 바인딩
  return f(2);
}

foo(1); // 3

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

function foo() {
  var f = (...args) => args[0];
  return f(2);
}

foo(1); // 2

메소드로 사용되는 화살표 함수

이야기 했듯이, 화상표 함수 표현은 메소드 함수가 아닌 속에 적당합니다. 메소드로 사용하려고 한면 무슨일이 발생하는지 봅시다.

'use strict';
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); // prints undefined, Window
obj.c(); // prints 10, Object {...}

 

화살표 함수는 자신의 this를 정의 ("bind" 바인드) 하지 않습니다.  Object.defineProperty()와 연관되 다른예:

new 연산자 사용

화살표 함수는 생성자로서 사용될 수 없으며 new와 함께 사용하면 오류가 발생합니다.

yield 키워드 사용

yield 키워드는 화살표 함수의 본문(그 안에 더 중첩된 함수 내에서 허용한 경우를 제외하고)에 사용될 수 없습니다. 그 결과, 화살표 함수는 생성기(generator)로서 사용될 수 없습니다.

함수 본문

화살표 함수는 "간결한 본문"이든 보통 "블록 본문"이든 하나를 가질 수 있습니다.

블록 본문 형태는 자동으로 값을 반환하지 않습니다. 명시된 return 문을 사용할 필요가 있습니다:

var func = x => x * x;                  // 간결한 구문, 암시된 "return"
var func = (x, y) => { return x + y; }; // 블록 본문이면, 명시된 "return"이 필요

객체 리터럴 반환

간결한 구문 params => {object:literal}을 사용한 객체 리터럴 반환은 예상대로 작동하지 않음을 명심하세요:

var func = () => {  foo: 1  };               // func() 호출은 undefined를 반환!
var func = () => {  foo: function() {}  };   // SyntaxError: function 문은 이름이 필요함

이는 중괄호({}) 안 코드가 일련의 문(즉 foo는 라벨처럼 취급됩니다, 객체 리터럴 내 키가 아니라)으로 파싱(parse, 구문 분석)되기 때문입니다.

객체 리터럴를 괄호로 감싸는 것을 기억하세요:

var func = () => ({ foo: 1 });

줄바꿈

화살표 함수는  파라메터와 화살표 사이에 개행 문자를 포함 할 수 없습니다.

var func = ()
           => 1; // SyntaxError: expected expression, got '=>'

파싱순서

화살표 함수 내의 화살표는 연산자가 아닙니다. 그러나 화살표 함수는 평범한 함수와 비교했을 때 operator precedence와 다르게 반응하는 특별한 파싱룰을 가지고 있습니다.

let callback;

callback = callback || function() {}; // ok
callback = callback || () => {};      // SyntaxError: invalid arrow-function arguments
callback = callback || (() => {});    // ok

다른 예

// empty 화살표 함수는 undefined를 반환
let empty = () => {};

(() => "foobar")() // "foobar" 반환

var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// 쉬운 배열 필터링, 매핑, ...

var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b);  // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2);       // [10, 12, 26, 0, 2, 36, 46]

// 더 간결한 프로미스 체인
promise.then(a => {
  // ...
}).then(b => {
   // ...
});

스펙

스펙 상태 설명
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Arrow Function Definitions' in that specification.
Standard 초기 정의.
ECMAScript 2017 Draft (ECMA-262)
The definition of 'Arrow Function Definitions' in that specification.
Draft  

브라우저 호환성

Feature Chrome Firefox (Gecko) Edge IE Opera Safari
Basic support 45.0 22.0 (22.0) (Yes)

No support

32 No support
Feature Android Android Webview Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support No support 45.0 22.0 (22.0) No support No support No support 45.0

Firefox 전용 주의사항

  • Firefox에서 화살표 함수의 초기 구현은 자동으로 엄격 모드이게 합니다. 이는 Firefox 24인 현재 변경되었습니다. 이제 "use strict"; 사용이 필요합니다.
  • 화살표 함수는 의미상(semantically) Firefox 3 (세부사항: JavaScript 1.8)에 추가된 비표준 expression closure와 다릅니다, expression closure의 경우 this를 렉시컬(lexically, 정적) 바인딩하지 않습니다.
  • Firefox 39 이전에, 줄 끝 문자(\n)는 화살표 함수 인수 뒤에 잘못 허용되었습니다. 이는 ES6 스펙을 따르도록 수정되었고 () \n => {} 같은 코드는 이제 이번 및 이후 버전에서 SyntaxError가 발생합니다.

참조

문서 태그 및 공헌자

 이 페이지의 공헌자: daehyoung, Geun-Hyung_Kim, Netaras, preco21, chiyodad, Jeeeyul
 최종 변경: daehyoung,