함께 성장하는 프로독학러

* arrow function은 함수선언(function declaration)과 완벽히 같지는 않다 본문

Programming/ES6

* arrow function은 함수선언(function declaration)과 완벽히 같지는 않다

프로독학러 2018. 4. 5. 15:38

안녕하세요, 프로독학러 입니다.


이번 포스팅에서는 ES6의 arrow function과 기존 자바스크립트의 함수선언(function declaration)의 차이점에 대해서 알아보도록 하겠습니다.

ES6로 넘어오면서 arrow function이 기존의 함수선언을 완벽히 대체할 수 있을거라 생각하시는 분들이 계실 것 같은데요, (저 역시도 그렇게 생각했습니다) 둘은 같은 듯 하지만 다른점이 있습니다.


일단 이를 이해하기 위해서는 this에 대한 이해가 필요합니다.

* this에 대해서 알아보려면 다음 링크를 참조하세요.

<자바스크립트, this가 무엇이냐>


ES6의 화살표함수(arrow function) 이전에는 모든 새로운 함수는 자신만의 this를 정의 했습니다(이 함수가 생성자인 경우는 새로운 객체, 엄격모드 함수 호출에서는 undefined, 함수가 '객체 메서드'로서 호출된 경우 문맥 객체 등).

하지만 이런 방식은 함수의 실행 방식에 따라 this가 달라지기 때문에 여러가지로 귀찮은 일이 생기기 마련이었습니다.


이를 해결하기 위해 ES6의 화살표 함수는 자신만의 this를 생성하지 않습니다.

즉, 화살표함수에서의 this는 원래의 문맥이 가진 의미를 갖습니다. 


이를 이해하기 위해 아래의 예제를 살펴보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
function origin(){
    console.log('inside of originFunc', this.foo);
    return {
        foo:20,
        bar: function(){
            console.log('inside of bar', this.foo);
        }
    }
}
 
origin.call({foo:10}).bar()
// inside of originFunc 10
// inside of bar 20
cs


예제의 첫 번째 줄에서 origin 이라는 함수를 정의 했습니다.

함수가 실행 될 때, 콘솔을 통해서 'origin함수의 안이다' 라는 메세지와 함께 this의 foo프로퍼티를 찍게 정의되어있습니다.

그리고 리턴 값으로 새로운 객체를 리턴합니다. 이 객체의 foo 프로퍼티는 20이고, bar는 메서드로 'bar프로퍼티 안이다'라는 메세지와 함께 해당 메서드를 가진 객체의 foo값은 찍어내게 정의되어있습니다.

이를 call메서드를 이용해 간접실행하면, 인자로 들어온 객체 (foo값이 10인 객체) 가 origin함수에서의 this로 정해지게 됩니다.

따라서 콘솔창을 통해 inside of originFunc 10 가 찍히게 됩니다.

콘솔이 찍히고 나면 새로운 객체를 리턴하게 됩니다(foo가20, bar메서드를 가진).

그리고 그 객체의 bar메서드를 실행했으므로 inside of bar 20가 콘솔창에 찍히게 됩니다.

(메서드로서 함수가 실행되면 해당 메서드가 정의된 객체가 this가 된다!)


1
2
3
4
5
6
7
8
9
10
11
12
13
function origin(){
    console.log('inside of originFunc', this.foo);
    return {
        foo:20,
        bar: ()=>{
            console.log('inside of bar', this.foo);
        }
    }
}
 
origin.call({foo:10}).bar()
// inside of originFunc 10
// inside of bar 10
cs


하지만 만약 리턴되는 객체의 bar 메서드에 화살표함수를 쓴다면 결과가 어떻게 달라질까요?

call메서드를 이용해 origin함수의 this객체를 foo값이 10인 객체로 지정하면 첫 번째 콘솔에는 아까와 동일하게 inside of originFunc 10 가 찍힙니다.

하지만 두 번째 콘솔에는 아까와 다르게 inside of bar 10 가 찍히는 것을 볼 수 있습니다.

이는 화살표함수가 자신만의 this를 만들지 않기 때문에 생긴 결과입니다.

화살표함수는 원래 문맥(여기서는 origin함수)의 this를 그대로 사용하기 때문에 {foo:10} 객체를 사용한 것입니다.


이를 통해 this를 함수의 실행 방식에 따라 다르게 생각할 필요가 없이 문맥에 따라 직관적으로 사용할 수 있게 되는 것입니다.


1
2
3
4
5
6
7
8
9
10
// ES5 function에서는 `this` Scope가 function안에 들어가면 변하기 때문에 새로운 변수를 만들어 씁니다.
var someVar = this;
getData(function(data) {
  someVar.data = data;
});
 
// ES6 Arrow Function에서는 `this` Scope의 변화가 없기 때문에 `this`를 그대로 사용하면 됩니다.
getData(data => {
  this.data = data;
});
cs


하지만 자신만의 this를 생성하지 않기 때문에 화살표함수는 arguments객체를 가질 수 없습니다.

화살표 함수의 장점과 단점을 잘 고려하여 함수의 선언을 이용할지 화살표함수를 이용할지 잘 선택하여 사용하시면 되겠습니다.

감사합니다.


**참고 자료 (항상 감사드립니다)

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98

https://beomi.github.io/2017/07/12/understanding_js_scope_function_vs_arrow/


*다녀가셨다는 표시는 공감으로 부탁드릴게요! (로그인 하지 않으셔도 공감은 가능합니다 ㅎㅎ)


Comments