【问题标题】:Variable becomes undefined when access in a class method在类方法中访问时变量变为未定义
【发布时间】:2020-02-18 12:52:54
【问题描述】:

我在构造函数中定义了一个类变量,它包含对导入的类实例的引用。

但是,当我尝试在我的类方法中访问该变量时,我不断收到该变量的 undefined

导出的类

import models from '../../database/models'

const {User} = models;

class UserRepository {
  constructor(){
    this.model = User;
  }

 async create({firstname, lastname, email, isadmin, password}){
  return await this.model.create({firstname, lastname, email, isadmin, password})
  }
}

export default new UserRepository();

使用导出类的类

import repository from './repository';
import { sendSuccessMessage } from '../../utils'

class UserController {
  constructor() {
    this.model = repository;
  }

  async createUser({ body }, res, next) {
    try {
      const result = await this.model.create(body);
      sendSuccessMessage(res, 200, result);
    } catch( e ){
      next(e)
    }
  }
}

export default new UserController();

但是,使用createUser 中的变量repository 目录,如下所示:

const result = await repository.create(body);

按预期工作。

当前调用链

// routes.js file
import controller from './controller'

export default [
  {
    path: '/signup',
    method: 'post',
    handlers: [controller.createUser] // createUser from class UserController
  }
]


// utitlity.js file
export const routesLoader = (routes, router) => {
 for (const route of routes) {
   const { path, handlers, method } = route;
   (router)[method](path, handlers);
 }
};

// app.js file
import express from 'express';
import routes from './routes.js';
import { routesLoader } from './utils';

const router = express.Router();

routesLoader(routes, router);

// server.js file
import http from 'http';
import app from './app';

const { PORT = 3000 } = process.env;

const server = http.createServer(app);

server.listen(PORT, () => {
  console.log(`server listening on localhost: ${PORT}`);
});

错误

TypeError: Cannot read property 'create' of undefined
at _callee$ (C:\Users\MYPC\Downloads\moch-shop-api-master\components\user/controller.js:16:39)
at tryCatch (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:45:40)
at Generator.invoke [as _invoke] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:271:22)
at Generator.prototype.<computed> [as next] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\regenerator-runtime\runtime.js:97:21)
at asyncGeneratorStep (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:3:24)
at _next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:25:9)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:32:7
at new Promise (<anonymous>)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\@babel\runtime\helpers\asyncToGenerator.js:21:12
at createUser (C:\Users\MYPC\Downloads\moch-shop-api-master\components\user\controller.js:70:28)
at Layer.handle [as handle_request] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\express\lib\router\index.js:275:10)
at cors (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:188:7)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:224:17
at originCallback (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:214:15)
at C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:219:13
at optionsCallback (C:\Users\MYPC\Downloads\moch-shop-api-master\node_modules\cors\lib\index.js:199:9)

使用的技术

@babel/node: "^7.8.4"
terminal: git bash
Os: windows

【问题讨论】:

  • 构造函数如何在 this.model = UserRepository 中获取 UserRepository;
  • this.model = UserRepository; 是否实际上将 而不是实例分配给 this.model
  • @VLAZ 我认为它正在分配类的实例,因为它是被导出的实例,而不仅仅是类名。
  • 在这种情况下如何导入?
  • @VLAZ,我刚刚注意到我打错了。我刚刚更新了问题。

标签: node.js express undefined babel-node


【解决方案1】:

您的方法 create 是一个实例方法。它需要是静态的才能工作

【讨论】:

    【解决方案2】:

    首先,您需要在使用之前正确导入UserRepository

    import UserRepository from 'path to UserRepository class';
    

    那么 在您的函数中使用self,如下所示:

    async createUser({ body }, res, next) {
     const self = this;
     try {
       const result = await self.model.create(body);
       sendSuccessMessage(res, 200, result);
     } catch( e ){
       next(e)
     }
    }
    

    我认为在 createUser() 函数中使用 self 比使用 this 更好。

    【讨论】:

    • 为什么上下文丢失了?
    • @VLAZ,看到这个答案我想到了同样的问题,难道是babel-node转译代码是原因?
    • @Deep Kakkar,我仍然有同样的问题,model 仍然是 undefined
    • @wokorodouyesamuel 也许?奇怪的是它会这样做,但这并非不可能 - 以前有过编译错误。调用堆栈有点奇怪,因为它显然创建了一个异步生成器。也许这是正确的,但还是有点奇怪。
    【解决方案3】:

    UserController.createUser 怎么称呼?听起来它的this 设置不正确。假设我们这样初始化类:

    const userController = new UserController();
    

    那么,缺少this 的一个原因可能是您只传递了对该方法的精确引用

    setImmediate(userController.createUser);
    

    而不是保留this的方式:

    setImmediate(() => {
       userController.createUser()
    });
    

    换句话说,您想使用点表示法调用方法并涉及类实例。

    【讨论】:

    • 我会更新问题以包括它是如何被调用的
    • @wokorodouyesamuel 谢谢,确实是问题所在:用保留this 的东西替换这个handlers: [controller.createUser],类似,我不知道它是否可能,但是:handlers: [() =&gt; { controller.createUser(); }]跨度>
    • 感谢您指出这一点,我会更仔细地研究。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 2013-09-08
    • 2023-04-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多