티스토리 뷰

이 내용은 아래 링크에서 동영상 강의도 같이 보실 수 있습니다.

[ 동영상 강의 보기 ]


화살표 함수 ( Arrow function )

ECMA Script 2015에 새로운 익명함수 정의 방법인 화살표 함수가 추가됐습니다.

사용방법은 아래와 같이 기존 함수 선언문법에서 function을 제거하고 괄호 뒤에 => 화살표를 추가해줍니다.

// 매개변수가 없을 경우
() => { ... }
// 매개변수가 한개인 경우 소괄호를 생략할 수 있습니다.
param => { ... } 
// 매개변수가 두개 이상인 경우 소괄호를 생략할 수 없습니다.
(param1, param2) => { ... } 

// 함수 내부 코드가 1줄이라면 중괄호도 생략 가능하고 실행 결과를 리턴합니다.
param => param + 1 

이런 간단한 함수 선언으로 인해 아래와 같이 코드 가독성이 높아졌습니다.

const numbers = [1, 2, 3, 4, 5];

// [2, 3, 4, 5, 6] 출력
console.log(numbers.map(function(number) { return number + 1 })); // 기존 방법
console.log(numbers.map(number => number + 1)); // 화살표 함수

화살표 함수는 간단한 문법 이외에도 this의 동작이 명확해졌습니다.

자바스크립트의 this

Java나 PHP등 대부분의 언어가 그렇듯 this의 용도는 클래스 내부에서 자신을 가리키는게 더 익숙합니다.
하지만 자바스크립트는 this가 아래와 같이 실행하는 위치마다 의미가 다릅니다.

함수 안에서의 this

function func() {
    console.log(this); // window 객체
    console.log(this === window); // true
}

func();

엄격모드에서 함수 안에서의 this

"use strict"

function func() {
    console.log(this); // undefined
}

func();

메소드 안에서의 this

const object = {
    func: function() {
        console.log(this); // object 객체
        console.log(this === object); // true
    }
};

object.func();

생성자 실행에서의 this

function SomeObject(name) {
    this.name = name;
    console.log(this); // 새로 생성된 객체 ( someObject 혹은 someObject2 )
}

const someObject = new SomeObject('someObject');
const someObject2 = new SomeObject('someObject2');

이렇게 함수가 임의로 this를 바인딩하기 때문에 일관성 없는 동작방식으로 개발자에게 많은 혼란을 줬습니다.

화살표 함수는 더이상 임의로 this를 바인딩 하지 않고 상위 스코프의 this를 가져옵니다.

일반 함수와 화살표 함수 비교

- 일반 함수

개발자가 원하는 this를 사용하기 위해 별도의 변수에 넣거나, bind()를 사용하는 등 불필요한 코드를 추가해야합니다.
function Person(name) {
    this.firstName = name;
}

Person.prototype.prefixName = function (arr) {
    // 아래 일반 함수에서 사용하기 위해 that이란 변수 생성
    const that = this;
    
    return arr.map(function (character) {
        // 일반 익명 함수에서 this는 window객체이므로 this.firstName === undefined
        // 따라서 위에서 정의한 that을 사용
        return character + ' ' + that.firstName;
    });
};

const person = new Person('철수');
console.log(person.prefixName(['김', '이']));
function Person(name) {
    this.firstName = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map(
        function (character) {
            return character + ' ' + this.firstName;
        }.bind(this) // 개발자가 임의로 this바인딩을 변경
    );
};

const person = new Person('철수');
console.log(person.prefixName(['김', '이']));

- 화살표 함수

this를 임의로 변경하지 않으니 별다른 코드 없이 개발자가 원하는 this를 사용할 수 있습니다.
function Person(name) {
    this.firstName = name;
}

Person.prototype.prefixName = function (arr) {
    return arr.map((character) => {
        // 화살표 함수에서 this는 상위 스코프에서 가져오므로 new 로 생성한 person 객체
        // 즉 this.firstName === '철수'
        return character + ' ' + this.firstName;
    });
};

const person = new Person('철수');
console.log(person.prefixName(['김', '이']))

화살표 함수를 사용해서는 안되는 경우

화살표 함수는 this를 변경하지 않아 콜백 함수로 사용하기 편합니다. 하지만 편하다는 이유로 무분별하게 사용할 경우 문제가 생깁니다.

- 메소드

아래와 같이 메소드를 화살표 함수로 정의할 경우 넘겨받을 this가 없기 때문에 this.name은 undefined를 리턴합니다.
const object = {
    name: 'object name',
    func: () => {
        console.log(this.name);
    }
};

object.func();

이와 같은 경우는 ECMA Script 2015에 추가된 "축약 메소드 표현"을 사용하는것으로 해결이 가능합니다.

비효율적인 반복코딩을 줄여줄 수 있는 축약 표현 등은 나중에 한꺼번에 다룰 예정입니다.

const object = {
    name: 'object name',
    func() {
        console.log(this.name);
    }
};

object.func();

- 생성자 함수 및 prototype

화살표 함수는 생성자 함수로 사용할 수 없습니다. 아래 코드는 "Person is not a constructor" 오류를 발생시킵니다.

const Person = (name) => {
    this.firstName = name;
};

const person = new Person('철수');

prototype역시 동일한 문제가 발생합니다. 아래와 같은 코드에서 this.firstName은 undefined입니다.

function Person(name) {
    this.firstName = name;
}

Person.prototype.prefixName = (lastName) => {
    // this.firstName === undefined
    return this.firstName + ' ' + lastName;
};

const person = new Person('철수');
console.log(person.prefixName('김'));

생성자 함수와 prototype는 ECMA Script 2015에 추가된 class문법으로 대체가능합니다. 자세한 class문법 사용방법은 따로 다루고 여기서는 class를 사용한 코드만 보여드리겠습니다.

class Person {
    constructor(name) {
        this.firstName = name;
    }

    prefixName(lastName) {
        return this.firstName + ' ' + lastName;
    }
}

const person = new Person('철수');

console.log(person.prefixName('김'));

- addEventListener 함수의 콜백 함수

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

button.addEventListener('click', (ev) => {
    // 넘겨받은 이벤트 객체의 target으로 클릭한 엘리먼트에 접근해야 합니다.
    console.log(ev.target);
});


댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함