자바스크립트 ES6 Arrow Function

2017-07-21

ES6 에 출현한 새로운 형태의 함수 표현 방법

const fn = function(){};
const arrowFn = () => {};

(v) => (v+1) //{}없이 사용, v+1이 리턴값
(v) => v+1 //()생략 가능

Arrow Function, this context

const obj = {
  runTimeout() {
    setTimeout(function(){
      console.log(toString.call(this)); //[object Window]
    }, 1000);
  },
  
  sayHi(){
    console.log("hi");
    console.log(toString.call(this));
  }
}

obj.runTimeout(); //[object Window]
obj.sayHi(); // hi [object Object]

위의 코드는 아무런 문제 없이 작동하는 코드이다, runTimeout은 settimeout때문에 이벤트큐에 등록 된뒤 실행되는 것이라 this가 해당 오브젝트가 아닌 윈도우이다. 우선 위에서 this가 가리키는 것이 무엇인지 잘 봐두고, 문제가 될 수 있는 상황을 아래서 살펴보자

const obj = {
  runTimeout() {
    setTimeout(function(){
      console.log(toString.call(this));
      this.sayHi(); //<========
      //typeError: this.sayHi is not a function
    }, 1000);
  },
  
  sayHi(){
    console.log("hi");
    console.log(toString.call(this));
  }
}

obj.runTimeout();

runTimeout 에서 sayHi를 실행하려면 this가 가리키는 것이 서로 다르기 때문에 오류가 난다.

const obj = {
  runTimeout() {
    setTimeout(function(){
      console.log(toString.call(this)); //[obejct Object]
      this.sayHi();
    }.bind(this), 1000); //<========
  },
  
  sayHi(){
    console.log("hi");
    console.log(toString.call(this)); //[obejct Object]
  }
}

obj.runTimeout(); // [obejct Object] hi [obejct Object]

위와 같이 .bind(this) 를 사용하여 해결하는 방법이 있다.

const obj = {
  runTimeout() {
    setTimeout(()=>{ //<========
      console.log(toString.call(this));
      this.sayHi();
    }, 1000);
  },
  
  sayHi(){
    console.log("hi");
    console.log(toString.call(this));
  }
}

obj.runTimeout();

또 다른 방법으로 Arrow function을 이용하여 해결할 수 있다.

Arrow function은 항상 this context를 실행되는 해당 context를 유지하는 특성이 있다.


reference