"这"对象在前面是空的('保存')

时间:2016-08-26 12:45:42

标签: mongoose

正如我在标题中描述的那样,当我想保存一个新的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。

2 个答案:

答案 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