화살표 함수의 this

이지훈·2022년 1월 22일
0

공부한것들

목록 보기
15/15
post-custom-banner

화살표함수의 this를 알아보자

this에 대해서는 조금 공부한 적이 있는데 일반적인 function과 화살표함수의 this처리방법이 달랐다. 그래서 이번에 화살표함수에 대해 좀 더 알아보며 이 부분도 함께 공부하기로 했다.

화살표함수

화살표함수는 함수를 선언할 때 function 키워드를 사용하지 않고 간편하게 작성할 수 있는 대안이다. 하지만 몇 가지 부분에서 function과는 다르게 동작한다.

  • this나 super 바인딩이 없고, methods로 사용될 수 없다.
  • new.target 키워드가 없다.

    new.target : 함수, 생성자가 new 연산자를 통해 호출되었는지를 감지.
    new 연산자로 인스턴스화된다면 new.target은 생성자, 함수참조를 반환.
    일반 함수 호출시 undefined

  • 명시적으로 스코프를 지정하는 call, apply, bind로 this를 지정할 수 없다.
  • 생성자로 사용할 수 없다 (new 키워드로 인스턴스 생성 불가)
  • 내부에서 yield를 사용할 수 없다

사용방법

기본 구문은 다음과 같다

()=>{ 구문 } // 구문을 실행하며 return을 별도로 표기해주어야함.
()=> 구문 // 구문의 실행 값을 즉시 반환한다. 하지만 객체 리터럴 표현을 반환하려면 괄호로 감싸야한다
()=>({key:value}); 
구조분해할당, 나머지 매개변수 등도 지원한다.
(param1=defaultValue1, param2, ...rest)=>{구문}
var f=([a,b]=[1,2],{x:c}={x:a+b})=>a+b+c;
f(); // 6

이렇게 간결하게 사용할 수 있어 좋다. 구문만 보면 더 짧고 보기쉽게 사용할 수 있으니 취향에 따라 마음껏 사용하면 좋아 보이지만 일반 함수와 다른 부분을 주의해야한다.

this

다른 것보다 this값이 바인딩되지 않는다는 것이 일반 함수와 가장 큰 차이인 것 같다.
화살표 함수에는 this가 없고, 화살표 함수 본문에서 this에 접근하면 외부에서 값을 가져온다.

예를 들면

let group = {
  title: "1모둠",
  students: ["보라", "호진", "지민"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

group.showList();

forEach에서 콜백으로 전달된 함수는 원래라면 this가 global 객체가 될 것이다. 하지만 화살표함수를 사용함으로써 this는 화살표함수 바깥에 있는 showList가 가리키는 대상인 group이 된다. 그래서 this.title을 alert 했을 때 group.title을 출력하는게 된다.

만약 forEach 내부의 콜백을 일반 함수로 선언했다면 this가 전역객체 또는 undefined가 되어 에러가 출력될것이다. (javascript.info에서는 undefined라고 되어있는데 크롬 개발자모드 콘솔로 해보면 this가 window로 나온다. 나는 strict mode 여부에 따라 달라지는것으로 추정하고 있다!)

이렇게 되는 이유로 처음에는 화살표 함수만의 this규칙이 따로 있는것이라 생각했는데 정말로 단지 this가 없는 거였다. this가 없기 때문에 this를 사용하려 하면 변수를 서칭하듯 this값을 외부 렉시컬 환경에서 찾게 되고 위와 같은 상황이 일어나는것이다.

위 forEach를 예로 들면 this를 접근하려 할때
화살표함수 -> showList 순서로 찾아가 this를 사용.

추가

화살표 함수에는 this뿐 아니라 일반 함수에서 인수에 접근할 수 있게 해주는 유사 배열 객체인 arguments도 없다고 한다.
그동안 모르고 혼용해서 썼는데 화살표 함수와 일반 함수를 적절하게 잘 활용해야겠다.

출처

profile
안녕하세요! 대학교 졸업한 이지훈입니다.
post-custom-banner

0개의 댓글