ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ES6 문법 - Arrow Function
    개발 2020. 4. 28. 23:42

    Arrow Function

    ES6부터 추가된 화살표 함수( Arrow Function ) 표현식은 함수 리터럴의 단축 표현이고 익명 함수입니다. ( 그렇다고 함수 리터럴과 완전히 같은 건 아니므로 주의해야 합니다. ) 화살표 함수는 다음과 같이 화살표 함수 표현식으로 사용할 수 있습니다.

     

    // 기존의 함수 리터럴로 함수를 정의한 코드
    let func = function (x){ return x + x; };
    
    // 화살표 함수 표현식으로 작성한 코드
    let func = (x) => { return x + x; };
    
    // 하지만 인수가 없으면 인수를 묶는 괄호를 생략할 수 없습니다.
    let func = () => { return x + x; };
    
    // 인수가 하나만 있다면 인수를 묶는 괄호를 생략할 수 있습니다.
    let func = x => { return x + x; };
    
    // 인수가 여러개 있을 경우 인수와 인수를 쉼표로 구분
    let func = (x, y, z) => { return x + y + z; };
    
    // 함수 몸통 안의 문장이 return 밖에 없다면 중괄호와 return 키워드를 생략할 수 있습니다.
    let func = x => x + x;
    
    // 함수 몸통 안에 return 문장만 있더라도 함수의 반환값이 객체 리터럴이면 객체 리터럴을 그룹 연산자인()로 묶어야 합니다.
    let func = (x, y) => ( {a: x, b: y} );
    
    // 화살표 함수도 즉시 실행 함수(IIFE)로 사용할 수 있습니다.
    (x => x + x)(5);  // 10

     

    또한 화살표 함수는 익명 함수이기 때문에 화살표 함수를 호출하기 위해서는 함수 표현식을 사용합니다.

    // ES5
    let func = function (x) { return x + x; };
    console.log(func(5));  // 10
    
    // ES6
    let func = x => x + x;
    console.log(pow(5));   // 10

     

    함수 선언문의 경우에는 호이스팅이 되어 함수가 선언된 시점의 앞, 뒤에서 함수호출이 가능하지만 함수 표현식은 호이스팅되지 않기 때문에 함수 선언 전에 호출하게 되면 에러가 나는 것을 우리는 알고 있습니다.

    따라서, 화살표 함수 또한 표현식이기 때문에 호이스팅이 되지 않아서 해당 함수 전에 함수호출을 하게 되면 에러가 납니다.

     

    함수 리터럴과 화살표 함수의 차이점

     

    1. this의 값이 함수를 정의할 때 결정됩니다.

     

    함수 리터럴로 정의한 함수의 this 값은 함수를 호출할 때 결정됩니다. 그러나 화살표 함수의 this 값은 함수를 정의할 때 결정됩니다.

    즉, 화살표 함수의 상위 스코프의 this 값화살표 함수의 this 값이 됩니다.

    화살표 함수의 this에 대해서는 화살표 함수( Arrow Function )에서의 this 바인딩 에서 더 자세히 다루고 있습니다.

    let obj = {
      foo : function(){
        console.log(this);  // {foo: ƒ}
        
        let func = function(){ console.log(this); }  // Window {parent: Window, ...}
        func();
        
        let func2 = () => console.log(this);  // {foo: ƒ}
        func2();
      }
    };
    
    obj.foo();

     

    2. arguments 변수가 없습니다.

     

    화살표 함수 안에는 arguments 변수가 정의되어 있지 않으므로 사용할 수 없습니다.

    let func = () => console.log(arguments);
    func();  // Uncaught ReferenceError: arguments is not defined

    3. 생성자로 사용할 수 없습니다.

     

    화살표 함수 앞에 new 연산자를 붙여서 호출할 수 없습니다.

    let Person = (name, age) => {
      this.name = name;
      this.age = age;
    };
    
    let person1 = new Person('hyojin' , 25);  // Uncaught TypeError: Person is not a constructor

     

     

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

     

     

    1. 화살표 함수를 메서드로 사용하기

     

    화살표 함수는 Lexical this를 지원하므로 콜백 함수로 사용하기 편리합니다. 하지만 화살표 함수로 메소드를 만드는 것이 불가능하지는 않지만 화살표 함수를 사용하는 것이 오히려 혼란을 불러오는 경우가 있으므로 주의해야 합니다. 

     

    다음은 화살표 함수를 메소드로 사용하면 어떤 문제가 있는지를 알아볼 예제코드입니다.

    let obj = {
      arrowFunc: () => console.log(this),
      func: function(){
        console.log(this);
      } 
    }
    
    obj.arrowFunc();  // Window {parent: Window,  …}
    obj.func();  // {arrowFunc: ƒ, func: ƒ}

    화살표 함수로 구현된 arrowFunc() 메서드와 일반 함수로 구현된 func() 메서드가 있습니다.

    각각의 메서드에서 this를 출력해 본 결과 obj.arrowFunc() 메서드의 this는 window가 되었고, func() 메서드는 함수 호출에 따른 this 바인딩으로 자신을 호출한 obj를 가리키게 됩니다.

    화살표 함수인 arrowFunc() 메서드는 일반 함수와 달리 상위 컨택스트인 전역 객체 window를 가리키는 것입니다.

     

    즉, 동적으로 결정되는 일반 함수와는 달리 화살표 함수의 this는 언제나 상위 스코프의 this를 가리킵니다.

     

    2. prototype

     

    화살표 함수로 정의된 메서드를 prototype에 할당하는 경우에도 객체의 메서드를 화살표 함수로 정의하였을 때와 같은 문제가 발생합니다.

    따라서 prototype에 메서드를 할당하는 경우에는 일반함수를 할당하여야 합니다.

    let Foo = {
      num: 10,
    }
    
    Object.prototype.say = () => console.log(this.num);
    
    Foo.say();  // undefined

     

    3. 생성자 함수

     

    화살표 함수는 생성자 함수로 사용할 수 없습니다. 생성자 함수는 prototype 프로퍼티를 가지며 prototype 프로퍼티가 가리키는 프로토타입 객체의 construntor를 사용합니다. 하지만 화살표 함수는 new가 되지 않기 때문에 당연히 prototype 프로퍼티도 가지고 있지 않습니다.

    let Foo = () => {};
    
    let foo = new Foo();  // Uncaught TypeError: Foo is not a constructor

     

    4. addEventListener 함수의 콜백 함수

     

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

    button.addEventListener('click', () => {
      console.log(this);  // Window {parent: Window, …}
    });

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

    일반함수를 사용했을 때에는 button을 잘 가리키지만 화살표 함수를 사용했을 때에는 화살표 함수의 this 바인딩에 따라서 상위 컨택스트인 전역 객체를 가리키게 됩니다.

     

     

    마지막으로 화살표 함수에서 가장 중요한 핵심 "this" 에 대해서는 화살표 함수 ( Arrow-Function )에서의 this 바인딩에서 다루고 있으니 이 컨텐츠에서 이어서 블로깅하도록 하겠습니다.

Designed by Tistory.