[JS] 화살표 함수를 주의해서 사용해야 하는 경우

nemo·2022년 3월 15일
1

JavaScript

목록 보기
15/23

1. 일반 함수와 화살표 함수의 this는 다르다.

일반 함수의 this

  • 일반적으로 함수의 this는 window 객체를 참조한다.
  • use strict를 사용한 엄격 모드에서는 window 객체 대신 undefined로 설정된다.
  • 또한 bind(), call(), apply() 메서드를 통해 this가 참조할 객체를 지정해줄 수도 있다.

아무튼 일반 함수의 this는 고정되지 않고 동적으로 결정된다는
게 포인트다.


화살표 함수의 this

화살표 함수의 this는 정적으로 결정된다. 화살표 함수의 this는 상위(부모) 스코프 값이 상속된다.
즉, 고정적으로 상위 스코프를 가리킨다는 말이다.

✋ 이벤트 핸들러에서 this
이벤트 핸들러 함수에서 this는 이벤트가 발생한 요소를 가리킨다.


아래 코드를 살펴보자.
이벤트 핸들러의 this는 이벤트가 발생한 요소를 가리키므로 첫번째 this는 box를 가리킨다.


const box = document.querySelector('.box');

box.addEventListener("click", function() {
  // this -> box
  this.classList.toggle("opening");
  setTimeout(function() {
    // this -> window
    this.classList.toggle("opening");
  }, 500);
})

// Uncaught TypeError: cannot read property "toggle" of undefined

그렇다면 setTimeout 함수 내의 this는 무엇을 가리킬까?
일반 함수로 작성되었으므로 window 객체를 가리킨다. 따라서 window 객체에는 opening class가 없으므로 오류가 발생한다.

이런 경우에 화살표 함수를 사용해 this가 상위(부모) 스코프에서 값을 상속받도록 하면 된다.

const box = document.querySelector('.box');

box.addEventListener("click", function() {
  // this -> box
  this.classList.toggle("opening");
  setTimeout(() => {
    // this -> box
    this.classList.toggle("opening");
  }, 500);
})



2. 화살표 함수를 주의해서 사용해야 하는 경우

2-1. 이벤트 핸들러

위 예제에서 이벤트 핸들러를 화살표 함수로 바꿔보자.

const box = document.querySelector('.box');

box.addEventListener("click", () => {
  // this -> window
  this.classList.toggle("opening");
})

화살표 함수의 this는 상위 스코프 값이 상속되며 고정이라는 걸 기억하자.
이벤트 핸들러를 화살표 함수로 사용하면 this는 이벤트가 발생한 요소가 아닌 window를 가리킨다. 아마도 의도한 대로 코드가 동작하지 않을 것이다.

2-2. arguments

arguments는 함수에 전달된 인수 값을 담은 배열 객체다.
arguments는 함수 내부에서 접근이 가능하다.

function foo () {
  console.log(arguments[0]);
}

foo("a", "b", "c"); // "a"

그런데 화살표 함수는 arguments에 접근하는 방식이 일반 함수와 다르다. 화살표 함수에서 arguments 객체는 부모 스코프의 값을 상속받는다. this와 비슷한 접근이라고 생각하면 된다.

const foo = () => {
  console.log(arguments[0]);
}

foo("a", "b", "c"); 
// ReferenceError: arguments is not defined at foo

화살표 함수로 arguments에 접근하려면 아래와 같이 rest 파라미터를 사용해 명시적으로 작성하면 된다.

const foo = (...arg) => {
  const pick = arg[0];
  console.log(pick); // "a"
}

foo("a", "b", "c"); 

위 코드를 일반 함수로 작성하면 아래와 같다.

const foo = function() {
  const pick = arguments[0];
  console.log(pick); // "a"
}

foo("a", "b", "c"); 

0개의 댓글