해결된 질문
작성
·
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
가 되어버리며, 결과적으로 this
가 undefined
로 로그에 찍히는 것입니다.
반면, 두 번째 방법인 userRouter.post('/signup', (req, res) => userController.signup(req, res));
에서는 화살표 함수를 사용하여 signup
함수를 감쌉니다. 화살표 함수는 자체 this
바인딩을 생성하지 않기 때문에, userController.signup
을 호출할 때 this
는 userController
를 가리키게 됩니다. 이러한 방식으로 this
의 컨텍스트를 유지할 수 있게 되어 signup
함수 내부에서 this.userService
에 접근할 수 있게 되고, 함수가 정상적으로 작동하게 됩니다.
JavaScript의 this
는 함수가 호출된 컨텍스트에 따라 결정되기 때문에, 이러한 문제를 해결하기 위한 방법으로 화살표 함수 사용 외에도 Function.prototype.bind
메소드를 사용하여 함수 호출 시 this
가 될 객체를 명시적으로 지정해주는 방법도 있습니다.
userRouter.post('/signup', userController.signup.bind(userController));
이 방법 또한 signup
함수가 UserController
인스턴스와 바인딩되게 하여 this.userService
에 정상적으로 접근할 수 있게 해줍니다.