每当我从mongo数据库中检索对象时,它都没有任何方法,我试图找出(1)原因和(2)解决方案.

总之,以下总结了问题:

(1) 我可以创建对象及其方法:

const newUser = new User(email, hashedPassword);
console.log(newUser.test); // correct - it’s not undefined

(2) 我可以将实例(及其方法)插入数据库(通过saveToDb):

const insertedUser = await collection.insertOne(this);

(3) 我可以从数据库中检索它(通过findByEmail):

const user = await collection.findOne({ email });

(4) 但它不再有任何方法:

if (!user) return; // temporary code
console.log(user); // correctly displays object keys and values
console.log('user.test', user.test); // undefined - why?

为什么会发生这种情况?我读过其他一些关于它的帖子,但它们似乎都使用mongoose,我在我的应用程序中没有使用它(也许我应该使用它?).This post没有得到答案,我认为这是一个类似的问题.

如果您有任何见解,我们将不胜感激,谢谢.

如有必要,请看以下课程:

export class User {
  email: string;
  hashedPassword: any;
  dateCreated: Date;

  constructor(email: string, hashedPassword: any) {
    this.email = email; // make email.toLowerCase(); 
    this.hashedPassword = hashedPassword; 
    this.dateCreated = new Date();
  }

  async saveToDb() {
    try {
      const collection = getCollection(USERS_COLLECTION_NAME);
      const sanitisedEmail = this.email.toLowerCase();
      const insertedUser = await collection.insertOne(this);

      console.log('THIS HAS BEEN INSERTED TO DB:', this);
      console.log('this.test:', this.test); // works
      this.test();

      const token = jwt.sign(insertedUser, sanitisedEmail, {
        expiresIn: 60 * 24,
      });
      return token;
    } catch (err) {
      throw err;
    }
  }

  test() {
    console.log('test() within class Fn');
    return 5;
  }

  static staticTest() {
    console.log('staticTest() within class Fn');
    return 6;
  }

  signToken() {
    const token = jwt.sign(this, this.email, {
      expiresIn: 60 * 24,
    });
    return token;
  }

  static async fetchAll() {
    try {
      const collection = getCollection(USERS_COLLECTION_NAME);
      const users = await collection.find().toArray();  
      return users;
    } catch (err) {
      throw err;
    }
  }

  static async findByEmail(email: string) {
    try {
      const collection = getCollection(USERS_COLLECTION_NAME);
      const user = await collection.findOne({ email });
      if (!user) return; // temporary code
      console.log('FOUND THIS USER: ', user); // works
      console.log('user.test', user.test); // undefined - key problem lies here...
      return user;
    } catch (err) {
      throw err;
    }
  }
}

推荐答案

通过查询方法(如findOne)返回的对象将是普通对象.它们不是类的实例,因为这些对象是作为JSON发送并保存在数据库中的,这不包括类信息、原型或方法.

所以你能做的就是改变你得到的对象的原型.或者更好的方法是,使用Object.create创建类的新实例,并使用Object.assign注入属性:

const user = Object.assign(
    Object.create(User.prototype), 
    await collection.findOne({ email })
);

现在,您的user对象将再次访问原型方法.

为了完整起见,我还将提到另一种 Select :

const user = await collection.findOne({ email });
Object.setPrototypeOf(user, User.prototype);

但请阅读Mozilla贡献者在setPrototypeOf上提供的免责声明:

根据现代JavaScript引擎优化属性访问的性质,更改对象的[[原型]]目前在每个浏览器和JavaScript引擎中都是一个非常缓慢的操作.此外,改变继承的影响是微妙而深远的,不仅限于在Object.setPrototypeOf(...)语句中花费的时间,还可以扩展到任何可以访问其[[原型]]已被改变的任何对象的代码.

Javascript相关问答推荐

如何在 cypress 中使用静态嵌套循环

如何修复我的数据表,以使stateSave正常工作?

将内容大小设置为剩余可用空间,但如果需要,可在div上显示滚动条

使用VUE和SCSS的数字滚动动画(&;内容生成)

如何使用TypeScrip设置唯一属性?

钛中的onClick事件需要在两次点击之间等待几秒钟

使每个<;li>;元素的 colored颜色 与随机生成的 colored颜色 列表不同(不重复

在D3条形图中对具有相同X值的多条记录进行分组

如何组合Multer上传?

为什么我不能使用其同级元素调用和更新子元素?

P5.js中矩形内的圆弧

为什么在运行于<;img>;事件处理程序中的JavaScript中x和y是不可变的?

JQuery使用选项填充HTMLSELECT并设置默认结果,默认结果显示为空

当达到高度限制时,如何裁剪图像?使用html和css

我如何才能让p5.js在不使用实例模式的情况下工作?

如何判断字符串是否只包含特定字符串

动画可以在Chrome上运行,但不能在Safari上运行

Cypress :条件测试过程中出错

在Reaction-Router-DOM v6中使用菜单的共享布局时出现问题

文本动画在其消失之前