Очевидно, в javascript, this
не присваивается значение, пока объект не вызовет функцию, тем самым связав this
с владельцем метода (вызывающим объектом).В приведенном выше вопросе я использую es6
функции стрелок, чья this
связана с ближайшей окружающей областью (лексической областью), поэтому не может найти свойство password
, которое определено в UserSchema , а непривязан к области действия this
в функции стрелки.
Пример:
var Utils = {
printName: function(somename) {
console.log(somename)
}
}
var person = {
firstName: "Gregory",
lastNames: ["Baltimore", "Barry", "Derrick", "Evanson"],
fullName: function() {
this.lastNames.forEach(lastname => {
//this points to person object
Utils.printName(this.firstName + " " + lastname) //output Gregory Baltimore Gregory Barry Gregory Derrick Gregory Evanson
})
}
}
person.fullName()
Примечание this
внутри функции стрелки es6 указывает на объект person, который является его статической областью (лексической).Давайте посмотрим на тот же кусок кода с точки зрения es5
var Utils = {
printName: function(somename) {
console.log(somename)
}
}
var person = {
firstName: "Gregory",
lastNames: ["Baltimore", "Barry", "Derrick", "Evanson"],
fullName: function() {
this.lastNames.forEach(function(lastname) {
//this points to global object
Utils.printName(this.firstName + " " + lastname) //output undefined Baltimore undefined Barry undefined Derrick undefined Evanson
})
}
}
person.fullName()
Вы заметите, что имя напечатано как неопределенное. Это потому, что в es5 this
выходит из области видимости и, следовательно, по умолчанию (Причуда Javascript) привязывается к глобальному объекту. В браузере этот глобальный объект - это окно в Nodejs, глобальный объект - это среда Nodejs (среда выполнения), если пользователь не определил ее (например, как при экспорте модуля) Чтобы решить мой вопрося по умолчанию использовал функцию es5, так как свойство пароля связано с глобальным объектом, который я определил как UserSchema. Таким образом, свойство паролябыло правильно решено
UserSchema.methods.comparePassword = function (candidatePassword, callback) {
//Now this is bound to the UserSchema object
bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
callback(err, isMatch)
})
}
Более подробно об этом можно узнать здесь Понимание JavaScript «этого» с помощью Clarity и Master It
и здесь также Функции стрелоки ключевое слово "это"