본문 바로가기

ECMAScript 6

화살표 함수 (=>)

화살표 함수

#1 화살표 함수 문법 (선언)

함수는 기본적으로 function 키워드를 이용해 작성하지만 화살표 함수는 function 키워드 대신 '=>'를 이용해 간단하게 함수를 선언할 수 있다.

그럼 기본 문법을 알아보자.

[ 매개변수 지정 ]
() => { ... }          // 매개변수가 없을 경우
x => { ... }          // 매개변수가 한 개인 경우, 소괄호 생략 가능
(x, y) => { ... }    // 매개변수가 여러 개인 경우, 소괄호 생략 불가능 

[ 함수 몸체 지정 ]

x => { return x * x }      // 한 줄 블록
x => x * x                 /* 함수 전체가 한 줄의 구문이라면 중괄호를 생략할 수 있으며
                           암묵적으로 변환됨. 위 표현과 동일 */

() => { return { a: 1 }; }
() => ({ a: 1 })            // 위 표현과 동일. 객체 반환 시 소괄호를 사용.

() => {                     // 여러 줄 블록
    const x = 10;
    return x = x;
};


#2 화살표 함수의 호출

화살표 함수는 '익명 함수'로만 사용할 수 있다.

따라서 화살표 함수를 호출하려면 '함수 표현식'을 사용한다.

ES5
var a = function (x) { return x * x; };
console.log(a(10));    // 100

ES6

const a = x => x * x;
console.log(a(10));    // 100

또는 콜백 함수로 사용할 수 있으며, 이 경우 일반적인 함수 표현식보다 간결하다.

ES5

var arr = [ 1, 2, 3 ];
var abc = arr.map(function (x) { return x * x; }); console..log(abc); // [ 1, 4, 9 ]

( map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.)

ES6

const arr = [ 1, 2, 3 ];
const abc = arr.map(x => x * x);
console.log(abc);    // [ 1, 4, 9 ]


#3 this

function 키워드로 생성한  일반 함수와 화살표 함수의 가장 큰 차이점은 'this'라고 할 수 있다.


#3-1 일반 함수의 this

일반 함수의 경우, 콜백 함수 내부의 this는 전역 객체 window를 가리킨다.

function Prefixer (prefix) { this.prefix = prefix; } Prefixer.protytpe.prefixArray = function (arr) { return arr.map(function (x) { return this.prefix + ' ' + x; (1) }); }; var pre = new Prefixer('Hi'); console.log(pre.prefixArray(['Lee', 'Kim']); // ["undefined Lee", "undefined Kim"]

위 코드에서 (1)의 this는 전역 객체 window를 가리킨다.

왜 그럴까?

왜냐하면 생성자 함수와 객체의 메소드를 제외한 모든 함수(내부 함수, 콜백 함수 포함) 내부의 this는 전역 객체를 가리킨다.

그럼 콜백 함수 내부의 this가 메소드를 호출한 객체를 가리키게 하려면 어떻게 해야할까?

3가지 방법이 존재한다.

1. that = this

function Prefixer (prefix) {
    this.prefix = prefix;
}

Prefixer.protytpe.prefixArray = function (arr) {
    var that = this;
    return arr.map(function (x) {
        return that.prefix + ' ' + x; 
    });
};

var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']);
// ["Hi Lee", "Hi Kim"]

2. map(func, this)

function Prefixer (prefix) {
    this.prefix = prefix;
}

Prefixer.protytpe.prefixArray = function (arr) {
    return arr.map(function (x) {
        return this.prefix + ' ' + x; 
    }, this);      // this : Prefixer 생성자 함수의 인스턴스
};

var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']);
// ["Hi Lee", "Hi Kim"]

3. bind(this)

// Function.prototype.bind()로 this를 바인딩한다.
function Prefixer (prefix) {
    this.prefix = prefix;
}

Prefixer.protytpe.prefixArray = function (arr) {
    return arr.map(function (x) {
        return this.prefix + ' ' + x; 
    }, bind(this));      // this : Prefixer 생성자 함수의 인스턴스
};

var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']);
// ["Hi Lee", "Hi Kim"]


#4 화살표 함수의 this

화살표 함수는 언제나 자신을 포함하는 외부 스코프에서 this를 계승 받는다.

이는 화살표 함수가 자신만의 this를 생성하지 않고 자신을 포함하고 있는 상위 컨텍스트로부터 this를 계승 받는다는 말이다.
function Prefixer(prefix) {
    this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
    return arr.map(x => `${this.prefix} ${x}`);
};

const pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']);
// ["Hi Lee", "Hi Kim"]


#4-1 화살표 함수를 시용하면 안 되는 경우

화살표 함수를 사용하면 안 되는 경우도 있다.

바로 살펴보자.

1. 메소드

첫 번째로 화살표 함수로 메소드를 정의하는 것은 피해야 하며 아래와 같이 정의한다.

[ 메소드를 위한 단축 표기법인 ES6 축약 메소드 표현 ]

const person = {
    name: 'Lee',
    sayHi() {
        console.log(`Hi ${this.name}`);
    }
};

person.sayHi();
// Hi Lee

2. prototype

두 번쨰로는 prototype이다.

[ 일반 함수 할당 ]

const person = {
    name: 'Lee'
};

Object.prototype.sayHi = function() {
    console.log(`Hi ${this.name}`);
};

person.sayHi();
// Hi Lee

3. 생성자 함수

화살표 함수는 생성자 함수로 사용할 수 없다.

화살표 함수는 prototype 프로퍼티를 가지고 있지 않다.

const Boo = () => {};

// 화살표 함수는 prototype 프로퍼티가 없음
console.log(Boo.hasOwnProperty('prototype');    // false

const boo = new Boo();
// TypeError: Boo is not a constructor

4. addEventListener 함수의 콜백 함수

addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 상위 컨텍스트인 전역 객체 window를 가리키게 된다.

따라서 addEventListener 함수의 콜백 함수에서 this를 사용하는 경우, function 키워드로 정의한 일반 함수를 사용해야 한다.

일반 함수로 정의된 addEventListener 함수의 콜백 함수 내부의 this는 이벤트 리스너에 바인딩된 요소를 가리킨다.

var button = document.getElementById('myButton');

button.addEventListener('click', function() {
    console.log(this === button);    // true
    this.innerHTML = 'Clicked button';
});


이렇게 해서 화살표 함수에 대해서 알아봤다.

처음에는 당연히 배우고 배운 것을 적용하기 힘들 것이지만 해보고 해보고 또 해본다면 어느새 익숙해져 있을 본인의 모습을 보게 될 것입니다.

저 또한 그러기 위해서 공부한 것을 블로그에 올리며 습득하고 있습니다.


읽어주셔서 감사합니다.


'ECMAScript 6' 카테고리의 다른 글

객체 리터럴 프로퍼티 기능 확장  (0) 2019.08.13
Spread 연산자  (0) 2019.08.12
Rest 파라미터  (0) 2019.08.11
ES6 템플릿 리터럴  (0) 2019.08.09
let, const 그리고 블록 레벨 스코프  (0) 2019.08.08