강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

YJ님의 프로필 이미지
YJ

작성한 질문수

(javascript) this 바인딩 관련 질문드립니다.

해결된 질문

작성

·

69

0

express를 활용하여 간단한 회원가입 api를 만들고 있는데 문제의 답은 알았지만 원리가 이해가 가지 않아 질문드립니다.

 

// user.route.js

const express = require('express');
const userRouter = express.Router();
const { UserController } = require('../controllers/user.controller');
const { UserService } = require('../services/user.service');
const userService = new UserService();
const userController = new UserController(userService);

// userRouter.post('/signup', userController.signup);
userRouter.post('/signup', (req, res) => userController.signup(req, res));

module.exports = { userRouter };
// user.controller.js

class UserController {
  userService;
  constructor(userService) {
    this.userService = userService;
  }

  signup(req, res) {
    const { email, password } = req.body;
    console.log(this);
    this.userService.checkEmail(email);
    this.userService.checkPassword(password);

    try {
      res.status(201).json({ message: 'SUCCESS_SIGNUP' });
    } catch (err) {
      res.status(err.status).json({ message: err.message });
    }
  }
}

module.exports = { UserController };

 

user.route.js에서

userRouter.Post('/signup', userController.signup);

이렇게 하면 userController.signup 내부의 console.log(this)가 undefined가 출력되고


userRouter.Post('/signup', (req, res) => userController.signup(req, res));

수정한 코드는 정상 작동 됩니다.

 

chatgpt에게 물어봤지만 답이 이해가 가지 않아 질문드립니다.

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

YJ님의 질문에 답변드립니다. 이 현상은 JavaScript의 this 바인딩 메커니즘 때문에 발생합니다.

첫 번째 코드에서 userRouter.post('/signup', userController.signup);를 사용하면, signup 함수가 호출될 때, 이 함수가 UserController 인스턴스에 바인딩된 상태가 아니라 단지 함수로서 호출됩니다. 이 때문에 signup 함수 내부의 this는 기대했던 UserController 인스턴스가 아니게 됩니다. 따라서, this.userService에 접근하려고 하면 undefined가 되어버리며, 결과적으로 thisundefined로 로그에 찍히는 것입니다.

반면, 두 번째 방법인 userRouter.post('/signup', (req, res) => userController.signup(req, res));에서는 화살표 함수를 사용하여 signup 함수를 감쌉니다. 화살표 함수는 자체 this 바인딩을 생성하지 않기 때문에, userController.signup을 호출할 때 thisuserController를 가리키게 됩니다. 이러한 방식으로 this의 컨텍스트를 유지할 수 있게 되어 signup 함수 내부에서 this.userService에 접근할 수 있게 되고, 함수가 정상적으로 작동하게 됩니다.

JavaScript의 this는 함수가 호출된 컨텍스트에 따라 결정되기 때문에, 이러한 문제를 해결하기 위한 방법으로 화살표 함수 사용 외에도 Function.prototype.bind 메소드를 사용하여 함수 호출 시 this가 될 객체를 명시적으로 지정해주는 방법도 있습니다.

userRouter.post('/signup', userController.signup.bind(userController));

이 방법 또한 signup 함수가 UserController 인스턴스와 바인딩되게 하여 this.userService에 정상적으로 접근할 수 있게 해줍니다.

YJ님의 프로필 이미지
YJ

작성한 질문수

질문하기