猫鼬模型静态/方法不保存“this”中的值

Posted

技术标签:

【中文标题】猫鼬模型静态/方法不保存“this”中的值【英文标题】:Mongoose Model static/method not holding the value in "this" 【发布时间】:2017-05-05 10:59:16 【问题描述】:

我正在尝试使用 mongodb 用户模型实现护照 js 身份验证。现在如您所见,我在用户模型上创建了一个方法。因此,当我将此方法应用于用户实例时,我希望“this”能够保存所有用户对象。但在这种情况下并没有发生这种情况。以下是一个工作代码,但我已经传递了一个额外的变量来使其工作。但我不想那样做。我在哪里犯错了?

下面是用于登录的护照配置文件

var passport = require('passport');
var User = require('../models/users');
var LocalStrategy = require('passport-local').Strategy;

passport.serializeUser((user, done)=>
  done(null, user.id);
);

passport.deserializeUser((id, done)=>
  User.findById(id, (err, user)=>
    done(err, user);
  );
);

passport.use('local.signin', new LocalStrategy(
usernameField: 'email', passwordField: 'password', passReqToCallback: true
,(req, email, password, done) => 
User.findOne(email:email, (err, user) => 
    if (err) return done(err)
    if (!user)return done(null, false, message:'This email is not registered')
      if (!user.validatePassword(password, user.password))
/**********************************************/
//is this field user.password really necessary?
/**********************************************/
          return done(null, false, message: 'Authentication Failed')
       else 
          return done(null, user);
      
  );
));

用户模型如下:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');

var userSchema = new Schema(
  salutation: type: String, required: false,
  firstname: type: String, required: true,
  lastname: type: String, required: false,
  email: type: String, required: true,
  password: type: String, required: true
);

userSchema.methods.validatePassword = (password, x) => 
  console.log(this); //this is returning null
  return bcrypt.compareSync(password, x);
/*********************************************************/
//I was excepting this.password to work instead of using x
/*********************************************************/


userSchema.methods.myCourses = (userId) => 
  console.log(this.enrolledFor);


module.exports = mongoose.model('User', userSchema);

【问题讨论】:

试试function (password, x) 而不是(password, x) => 嗨@GrégoryNEUT,感谢您的帮助。这件事工作得很好。但我的问题是console.log(this) 上方的行返回了一个空值。但这应该返回一个用户对象。至少这是我期望它做的:-( 问题是当你使用箭头函数(ES语法)时,函数内部的上下文是继承的。如果即使使用常规上下文,您也可以从此处访问用户,但您可以尝试。 哦……它成功了。我不知道 => 和函数之间的细微差别......将需要阅读它们。感谢您的指导。 我把它作为答案来结束你的问题。 【参考方案1】:

与函数表达式相比,箭头函数表达式的语法更短,并且不绑定自己的 this、arguments、super 或 new.target。箭头函数始终是匿名的。这些函数表达式最适合非方法函数,它们不能用作构造函数。 developer.mozilla

【讨论】:

【参考方案2】:

ECMA2015 标准也称为 ES6,允许使用箭头函数,这些函数从上层上下文继承它们的上下文。

解决办法是使用正则函数语法。

userSchema.methods.validatePassword = function (password, x) 
  console.log(this); //this is returning null
  return bcrypt.compareSync(password, x);
/*********************************************************/
//I was excepting this.password to work instead of using x
/*********************************************************/

----------

Article about arrow functions

箭头函数——也称为“胖箭头”函数,来自 CoffeeScript (一种转编译语言)是一种更简洁的写作语法 函数表达式。他们使用了一个新的令牌 =>,它看起来像一个 胖箭头。箭头函数是匿名的并且改变了 this 的绑定方式 在函数中。

箭头函数让我们的代码更简洁,简化函数 范围和 this 关键字。它们是一条线的迷你功能, 像 C# 或 Python 等其他语言中的 Lambda 一样工作。 (也可以看看 javascript 中的 lambda 表达式)。通过使用箭头函数,我们避免了 键入 function 关键字,return 关键字(它隐含在箭头中 函数)和大括号。

【讨论】:

【参考方案3】:

在使用 Mongoose Schema.methods 或 Schema.statics 时不要使用箭头函数,因为箭头函数不像函数表达式那样绑定 this 关键字。所以基本上,当您尝试使用箭头函数作为 Schema.method() 的参数时,每次从 Schema 中引用定义值时都会得到 undefined。

【讨论】:

以上是关于猫鼬模型静态/方法不保存“this”中的值的主要内容,如果未能解决你的问题,请参考以下文章

静态方法的猫鼬继承

猫鼬模式预保存中的 ESLint 意外“this”错误

打字稿:猫鼬模式的静态方法

猫鼬静态方法返回一个蓝鸟承诺

普通方法,静态方法,类方法

扩展模式猫鼬中的“虚拟”继承方法不起作用