猫鼬模型静态/方法不保存“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”中的值的主要内容,如果未能解决你的问题,请参考以下文章