호다닥

Javascript : 초보자를 위한 화살표 함수 본문

Javascript

Javascript : 초보자를 위한 화살표 함수

3jun 2018. 7. 21. 12:56

JavaScript: Arrow Functions for Beginners

출처 : codeburst.io, Brandon Morelli

해당 내용은 Brandon Morelli의 article을 개인적으로 번역한 내용이며, 잘못 번역된 부분이 있을 수 있습니다. 원문은 위에 적힌 주소에서 확인하실 수 있습니다.

 

 

 

 

 

Benefit #1 : Shorter Syntax

화살표 함수의 첫번째 이점은 문법을 간결하게 할 수 있다. 

 

우선 일반인 함수를 한번 보자.

function funcName(params) {
   return params + 2;
 }
funcName(2);
// 4

 

위 코드는 화살표 함수를 만들어야 하는 2가지 이유 중 한 가지에 대해 잘 보여준다. : 문법을 짧게 할 수 있다. 

화살표 함수를 사용하면 위 코드를 한 줄로 만들 수 있다. 

var funcName = (params) => params + 2
funcName(2);
// 4

 

위 예제는 극단적으로 간소화 되었지만, 요점을 잘 보여주고 있다. 

화삼표 함수의 문법에 대해 좀 더 깊게 살펴보도록 하자. 

(parameters) => { statements }

 

만약 우리가 어떠한 parameters도 가지고 있지 않다면 우리는 화살표 함수를 아래와 같이 표현할 수 있다. 

() => { statements }

 

만약 하나의 parameter만을 가지고 있다면 괄호는 생략이 가능하다. 

parameters => { statements }

 

마지막으로 만약 표현식을 return한다면 중괄호 또한 생략할 수 있다. 

parameters => expression
// is equivalent to:
function (parameters){
  return expression;
}

 

이제 기본적인 문법에 대해 공부를 했으니 예제를 통해 실습을 해볼 것이다. 

크롬 개발자 콘솔을 열고 아래 코드들을 따라 작성해보자.

var double = num => num * 2

 

우리는 변수 double에 화살표 함수를 할당했다. 화살표 함수에는 num이라는 한개의 parameter만 있다. parameter가 한개 뿐이므로 우리는 parameter 주위의 괄호를 생략했다. 

또한 우리는 num * 2 의 value를 return하고자 하므로 표현식 외부의 중괄호 또한 생략했다. 

이제 아래 예제 함수들을 호출해보고 결과값을 확인해보자. 

double(2);
// 4
double(3);
// 6

 

 

Benefit #2 No binding of this

2번째 이점 this를 binding하지 않는다. 

 

이 부분을 공부하기 에 앞서 우리는 this에 대해 어느정도 이해하고 있어야 한다. 

 

일반적인 함수와 달리 화살표 함수는 this를 bind하지 않는다. 대신 this는 사전적으로 bound된다. ( 예를 들어 this는 original context로부터의 의미를 계속 유지한다. )

 

실습예제를 통해 좀 더 자세히 살펴보자. 콘솔에서 생성자 함수를 만든 후에 인스턴스를 만들어보자. 

function Counter() {
  this.num = 0;
}
var a = new Counter();

 

지난 번에 공부했듯이 생성자함수와 this의 value는 새로 만들어진 객체에 bound 된다. 위 예시에서는 a 객체이다. 

이 때문에 console.log a.num 의 결과값이 0이 된다. 

console.log(a.num);
// 0

 

만약 우리가 a.num의 값을 매초마다 증가시키고 싶다면? 우리는 setInterval() 함수를 사용할 수 있다. setInterval()은 설정된 밀리세컨드 후에 또 다른 함수를 호출하는 함수이다. 위 Counter 함수에 setInterval 함수를 추가해보자. 

function Counter() {
  this.num = 0;
  this.timer = setInterval(function add() {
    this.num++;
    console.log(this.num);
  }, 1000);
}

 

추가한 this.timer 변수와 setInterval 함수를 제외하면 이전의 코드와 동일한 코드이다. 매 1000 밀리세컨드(1초)마다 코드는 실행된다. this.num은 1씩 증가하여 콘솔로그에 출력될 것이다. 

  

콘솔에서 Counter의 인스턴스를 다시 생성할 것이다. 

var b = new Counter();
// NaN
// NaN
// NaN
// ...

 

이 코드를 콘솔에서 실행하면 화면에 매초마다 함수가 log됨을 확인할 수 있다. 그러나 그 결과값은 우리가 기대했던 값이 아니라 NaN (Not a Number) 가 log된다. 무엇이 잘못되었을까?

중요한 것은 아래 코드를 실행함으로써 interval을 중단시켜야한다. 

clearInterval(b.timer);

 

setInterval 함수는 선언된 객체에서 사용될 수 없다. 뿐만 아니라 new keyword와 함께 호출될 수 없다. (오직 counter() 함수에서 사용된다.) 그리고 call, bind, apply 함수도 사용할 수 없다. 

setInterval은 단지 보통함수일 뿐이다. 사실 setInterval에서 this의 value는 글로벌 객체에 bound된다. 

this의 value를 logging 함으로써 이 이론을 테스트해보자.

function Counter() {
  this.num = 0;
this.timer = setInterval(function add() {
    console.log(this);
  }, 1000);
}
var b = new Counter();

 

여기서 볼 수 있듯이 window 객체는 매초마다 log된다. 아래 코드를 통해 interval을 초기화하도록 한다. 

clearInterval(b.timer);

 

다시 원래의 함수로 돌아와서, 원래의 함수는 this.num이 window 객체의 num property가 되기 때문에 NaN이 logging된다. 

(window.num은 존재하지 않는다.) 그리고 this.num은 우리가 만든 b 객체 (b.num)이 아니다. 

 

우리는 화살표 함수를 이용해서 이것을 fix할 수 있다. 우리는 this를 bind하지 않는 함수가 필요하다. 

화살표 함수를 이용하면 this는 스코프에서 원래의 binding을 지속적으로 유지한다. 원래의 Counter 함수의 setInterval을 화살표 함수로 바꿔보자.

function Counter() {
  this.num = 0;
  this.timer = setInterval(() => {
    this.num++;
    console.log(this.num);
  }, 1000);
}
var b = new Counter();
// 1
// 2
// 3
// ...

 

이제 콘솔이 증가된 숫자들을 logging하기 시작하면서 정상적으로 기능함을 확인할 수 있다. Counter 생성자 함수에 의해 binding되며 만들어진 원래의 this가 유지되었다. 

setInterval 함수 내부에서 this는 새롭게 만들어진 b 객체에 bound되어 있다. 

 

다시 아래의 코드로 interval을 초기화 하고,

clearInterval(b.timer);

 

개념을 좀 더 확실히 이해하기 위해 우리는 다시 화살표 함수 내부의 this를 logging해보자. 우리는 Counter함수 내부에 that 이라는 변수를 만들고, setInterval 함수에서의 this의 value가 부모함수인 Counter에서의 this의 value와 같다면 true값을 출력할 것이다. 

function Counter() {
  var that = this;
this.timer = setInterval(() => {
    console.log(this === that);
  }, 1000);
}
var b = new Counter();
// true
// true
// ...

 

기대했던 대로 true가 매 시간마다 출력됨을 확인했고, 이제 다시 interval을 초기화 함으로써 작업을 종료하면 된다. 

clearInterval(b.timer);

 

 

 

 

Conclusion 결론

이 글을 통해 화살표 함수의 2가지 이점에 대해 이해했으면 한다. 

  1. Shorter Syntax     문법을 간소화 한다.
  2. No binding of this     this가 binding 되지 않는다. 
이 글에서 설명한 특징들 외에도 화살표 함수에 대한 더 많은 정보가 있지만, 이 글을 이해하면 앞으로 학습을 하는데 분명 도움이 될 것이다. 

 

 

 

 

 

 

Comments