findOne 检索到的对象实例没有任何方法

用户8758206

每当我从我的 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?

为什么会这样?我已经阅读了一些关于它的其他帖子,但它们似乎都使用猫鼬,我没有在我的应用程序中使用它(也许我应该使用它?)。这篇文章没有得到答案,我认为这是一个类似的问题。

任何见解将不胜感激,谢谢。

万一需要看,这里是类:

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对象将再次可以访问原型方法。

为了完整起见,我还将提到替代方案:

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

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章