sc
получает значение из-за закрытия.Когда вложенная функция, возвращаемая score()
и оператором if
if (correct)
, имеет значение true, оценка увеличивается.Ниже приведен общий фрагмент кода.
function score(){
let sc = 0;
return function(correct){
if(correct){
sc++; //this is the same variable is upper scope.
console.log(sc)
}
return sc;
}
}
let temp = score();
temp(true);
temp(true);
Таким образом, в приведенном выше фрагменте внешняя функция score
вызывается только один раз и выполняет две функции:
- инициализирует переменную
sc
0
- функция возврата, в которой
sc
будет ссылаться на переменную sc
, созданную в верхней области видимости.
Это используется только для предотвращения создания глобальныхпеременная
Рассмотрим еще один простой фрагмент.
let count = 0;
function counter(){
count++;
console.log(count)
}
counter();
counter();
counter();
В приведенном выше фрагменте родительская область действия является глобальной, а дочерняя область - областью действия.Теперь переменная count
присутствует внутри counter()
(даже если она не объявлена внутри counter()
) из-за закрытия.
- Теперь в первом фрагменте функция
score()
имеет видточно так же, как глобальная область (во втором фрагменте), - В первом фрагменте возвращаемая функция
return function(correct){...}
аналогична вложенной функции counter()
во втором фрагменте. - и
sc
переменнаяэто как переменная count
.
Не могли бы вы просто объяснить prototype.checkAnswer
немного больше
Этот метод принимает два аргумента.ans
и callback
.
Рассмотрим строку в функции nextQuestion()
questions[n].checkAnswer(parseInt(answer), keepScore);
Теперь, если вы заметили, что в функцию переданы два параметра.Один - это номер правильного ответа, а другой - обратный вызов (функция, которая передается другой функции, будет вызвана позже).
Мы передаем keepScore
, который я объяснил выше, это функция, возвращаемая score()
то есть function(correct){...}
.Теперь эта функция вызывается внутри метода-прототипа.Этот обратный вызов возвращает значение sc
, которое объявлено в его родительской функции score
.И затем он отображается с помощью this.displayScore
Теперь, с чем вы, возможно, перепутали, это переменная sc
в prototype.checkAnswer
.Эта переменная просто для предотвращения двойной записи this.displayScore();
Функция может быть записана как:
Question.prototype.checkAnswer = function(ans, callback) {
if (ans === this.correct) {
console.log('Correct answer!');
this.displayScore(callback(true));
} else {
console.log('Wrong answer. Try again :)');
this.displayScore(callback(false));
}
}
Даже если мы объявим другую переменную sc
в prototype.checkAnswer
не имеет отношения к переменной sc
внутри score()
.Это совершенно разные переменные, поскольку переменные, объявленные с помощью var
, имеют область действия функции.
Создайте фрагмент кода:
function score(){
var sc = 0;
return function(){
sc++;
console.log(`I am sc of score: ${sc}`);
return sc;
}
}
let temp = score();
function wrapper(callback){
var sc = 0;
console.log(`I am sc of wrapper: ${sc}`);
callback();
}
wrapper(temp)
wrapper(temp)
wrapper(temp)
wrapper(temp)