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

时间:2016-12-20 09:22:27

标签: javascript node.js mongodb mongoose passport.js

我试图用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);

3 个答案:

答案 0 :(得分:1)

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   (反编译语言)是一种更简洁的写作语法   函数表达式。他们使用一个新的令牌,=&gt ;,看起来像一个   胖箭头。箭头函数是匿名的,并改变了它绑定的方式   在功能。

     

箭头函数使我们的代码更简洁,并简化了功能   范围和这个关键字。它们是单行迷你功能   像C#或Python等其他语言的Lambdas很像。 (也可以看看   JavaScript中的lambdas)。通过使用箭头功能,我们避免必须   键入function关键字,返回关键字(它隐含在箭头中   函数)和大括号。

答案 1 :(得分:0)

  

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

答案 2 :(得分:0)

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