삽질방지 - this, bind

치맨·2023년 4월 4일
1

삽질방지

목록 보기
4/5
post-thumbnail

목차

문제발생

우아한 테크코스에서 진행한 프로젝트 중 하나인 브릿지게임 프로젝트를 진행하던 중 코드를 분리하여 서로 영향을 받지 않도록 하고, 코드의 효율적인 재사용을 위해 MVC 디자인 패턴을 사용하여 리팩토링을 진행중이었습니다.

입력을 받는 부분을 InputView객체에 만들었고, 입력받은 값을 통해 처리를 Controller 부분에서 하려고 했습니다.

Controller의 requestBridgeSize 함수에서 InputView의 readBridgeSize 함수를 호출하면서 콜백함수로 Controller의 내부 메서드인 this.checkBridgeSize 함수를 넘겨줬습니다.

InputView의 readBridgeSize함수를 통해 Console.readLine()를 사용하여 사용자에게 입력값을 받고, 콜백함수로 넘겨줬습니다.

콜백함수인 checkBridgeSize(size)함수에서 입력값을 받고, 유효성 검사를 진행했습니다. 이후 검사를 통과하면 Controller 내부 메서드인 this.setGame()를 호출하는데 아래와 같은 문제가 발생했습니다.

문제원인

undefined을 읽을수 없다? 어느 부분이 문제인지 한참을 고민하다가 this를 console.log로 찍어봤습니다.

this의 값이 없다???????????

대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정됩니다.
출처 : JavascriptMDN

그렇다면 어디서 호출이 되었는가? 다시 처음부터 차근차근 알아보겠습니다.

  1. 시작부분
    인자로 넘겨주었지만, 호출이 되진 않았습니다.
  1. InputView
    또한 callback함수로 인자로 받아서, 입력값을 인자로 Console.readLine 함수에 콜백함수로 넘겨주었습니다.
  1. Console.readLine
    또한 callback함수를 question함수로 넘겨주었습니다.

참조 : 참조 NodeJs 공식문서

  1. rl.question
    NodeJs의 공식문서에 의하면 callback함수가 일반함수 내부에서 호출 됩니다. 따라서 this는 전역객체를 가리키는 것입니다.

  1. 최종적으로 this는?
    최종적으로 this는 전역객체인 global 객체를 가리키게 됩니다. 하지만 console.log를 통해 this를 확인 했을때 왜 this는 global객체가 아닌 undefined가 출력이 될까요?
    스스로 Test를 한번 해봤습니다.

1. 일반함수가 클래스 내부에서 선언됐을때

결과 => undefinded

2. 일반함수가 클래스 외부에서 선언됐을때

결과 => global객체

결과

  • 클래스는 따로 stict모드를 선언하지 않아도 strict모드가 적용되어 있으며, strict모드가 적용되었을때 일반함수에서의 this는 undefined를 가리키게 됩니다.
    따라서 클래스 내부에서 선언한 일반함수의 this는 전역객체인 global객체를 가리키는것이 아닌 undefined를 나타냅니다.

  • 이와 반대로 클래스 외부에서 선언된 일반함수의 this는 strict모드가 적용되지 않아 this가 가리키는것은 전역객체인 global객체를 가리키게 되는것입니다.

결과적으로 BridgeController 클래스의 내부에서 선언했기 때문에 undefined를 출력하게 됩니다.

  1. 마지막으로 Chat GPT에게 rl.question에서 호출된 콜백함수의 this에 대해 물어보았습니다.

문제해결

  • this.setGame의 this를 현재 BridgeController 클래스의 this로 바꿔주면 됩니다.

  • 이를 해결하기 위해서 처음 InputView의 readBridgeSize 함수를 호출한 부분으로 돌아가서 bind함수를 통해 this를 넘겨줍니다.

  • 이때 넘겨주는 this는 클래스의 메서드에서 호출한 this이기 때문에 BridgeController 클래스가 만든 인스턴스를 바인딩 하게 됩니다.

bind함수에 대해 궁금하시다면 → Javascript MDN

profile
기본기가 탄탄한 개발자가 되자!

0개의 댓글