-06- This & arrow function

mintgranita·2024년 3월 9일

JS101

목록 보기
6/9
post-thumbnail

This 키워드

this키워드란 실행문맥이 하나씩 가지는 변수로서 함수가 호출될때 생성됩니다.

const cruise = {
  name: "Tom",
  year: 1962,
  calcAge: function () {
    return 2022 - this.year;
  },
};// 여기서 this는 cruise를 가르킴...

console.log(cruise.calcAge()); // 60

this키워드가 있는 현재 위치에서 함수가 어떤 상황에서 호출되었는지 알려줍니다. (어떤 함수가 어디에 붙어있는가?) 다시말해 this 키워드가 가리키는 값은 함수가 호출된 상황에 따라 달라진다는 것입니다.

상황에 따라 달라지는 This

this 키워드가 쓰이는 대표적인 상황은 메서드 호출입니다.

*메서드: 객체에 붙어있는 함수

const number = {
  variable: 003,
  varMethod: function() {
      return this.variable;
  }
};
console.log(number.varMethod());
// prints: 003

메서드 호출에서의 this키워드의 값은 메서드가 붙어있는 객체입니다.

일반 함수호출에서의 this

function f1() {
   return this;
}
// In a browser:
f1() === window;
// true  // In Node:
f1() === global; // true

일반적인 함수호출을 할때 this의 값은 browser에서는 window객체이고, node 환경에서는 global객체를 가리킵니다.

*strict mode

function f2() {
'use strict';
// see strict mode  
  return this;
}
f2() === undefined; // true

엄격모드에서는 this는 undefined입니다.

Event listener

this가 이벤트 리스너에서 사용된 경우 이벤트 리스너가 붙어있는 엘리먼트를 가리키게 됩니다. 이는 이벤트의 현재 타겟과 같습니다.

my_element.addEventListener('click', function (e) {
  console.log(this.className) // my_element의 className 기록
  console.log(e.currentTarget === this) // `true` 기록
})

화살표 함수와 This

ES6부터 도입된 화살표 함수는 자체적으로 This를 가지지 않습니다. 그렇기 때문에
다음과 같이 앞의 코드의 함수 선언을 화살표 함수로 바꾸면 문제가 생기게 됩니다.

my_element.addEventListener('click', (e) => {
  console.log(this.className) // 경고: `this`가 `my_element`가 아님
  console.log(e.currentTarget === this) // `false` 기록
})

아래와같이 객체의 this를 다룰 때는 문제가 없지만, 객체에 담긴 함수를 다른함수의 콜백 함수로 사용하는 경우 문제가 생기게 됩니다.

const validator = {
  message: "는 유효하지 않습니다. ",
  setInvalidMessage(field) {
    return ` ${field}${this.message} `;
  },
};

validator.setInvalidMessage("도시"); // 도시는 유효하지 않습니다.

아래의 코드에서는 this가 map메서드 안의 콜백함수에서 선언되었습니다. 그렇다면 이때의 this가 선언된 상황은 메서드 호출이 아니라 일반 함수 호출이 되어 this가 가리키는 값은 window 혹은 global객체입니다 메세지 속성이 없기 때문에 에러가 생기게 됩니다.


const validator = {
  message: "는 유효하지 않습니다. ",
  setInvalidMessages(...fields) {
    return fields.map(function(field) {
      return ` ${field}${this.message} `;
    });
  },
};

validator.setInvalidMessage("도시"); 

이런 문제는 화살표 함수를 이용해서 해결할 수 있습니다. 화살표 함수는 자체적으로 문맥을 생성하지 않고 화살표 함수가 둘러쌓인 함수의 문맥을 따르게 됩니다. 따라서 아래코드의 this가 가리키는 값은 validator 객체입니다.


const validator = {
  message: "는 유효하지 않습니다. ",
  setInvalidMessages(...fields) {
    return fields.map(field => {
      return ` ${field}${this.message} `; //여기서 this는 setInvalidMessages의 문맥을 가리킴.
    });
  },
};

validator.setInvalidMessage("도시"); // 도시는 유효하지 않습니다.

이미 실행문맥이 있는 상황에서 다른함수로 화살표 함수를 이용하면 문맥혼동을 피하게 해줍니다.

결론: this 키워드는 함수가 호출된 상황에 따라 그 값이 달라진다. 화살표 함수는 자체적으로 this의 문맥을 생성하지 않으므로, 여러 개의 함수가 겹쳐저 문맥이 혼동될 때는 화살표 함수로 문맥 혼동을 피할 수 있다.

참고자료:

Mdn -EventTarget.addEventListener()
Mdn -this
The complete javascript course -Jonas Schmedtmann-
자바스크립트 코딩의 기술 -화살표 함수로 문맥혼동을 피하라

profile
UX광인이 되고싶어요

0개의 댓글