正如我在标题中描述的那样,当我想保存一个新的mongoose文档时,pre('save')
方法会触发,但其中的this
元素是一个emtpty对象。
测试片段:
var schema = new mongoose.Schema({
password:String
})
schema.pre('save',(next)=>{
console.log(this)
next()
})
var model = mongoose.model('Test',schema)
var test = new model({
password:'testpass'
})
test.save()
我无法看到这个基本代码的问题。
我使用的是Mongoose v4.5.9。
答案 0 :(得分:41)
无论出于何种原因,您的函数都不能使用es6箭头语法
schema.pre('save', function(next) {
console.log(this)
next()
})
会工作吗?我目前不知道为什么。
答案 1 :(得分:5)
来自用户的答案" unR"是正确的。在预保存功能上使用箭头功能时,无法使用this
。您还可以在所有其他类型的mongoose模式函数中找到它。我已经扩展了这个答案,以帮助澄清为什么会发生这种情况。
这打破了:
schema.pre('save', (next) => { // arrow function
console.log(this);
next();
});
这有效:
schema.pre('save', function preSave(next) { // regular function
console.log(this);
next();
});
原因:
问题出现是因为箭头功能如何处理" 范围"与常规功能不同。箭头函数不会在函数中保留范围,而是强制从外部或周围函数继承范围(这意味着它将覆盖exampleMethod.bind(this)
等函数)。在上面的情况;没有外部函数,因此this
值将等于undefined
。
但是,当您使用常规函数声明时,可以使用.bind()
方法通过mongoose覆盖范围。因此,它们将函数绑定到模式对象,这允许您访问函数中的模式属性和函数。
以下是有关箭头功能及其工作原理的有用资源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions