I'm wondering why I have to use the variable keepScore to make my code works.
After delete var I would write:
questions[n].checkAnswer(parseInt(answer), score())
but then point amount could be only 0 or 1 - var sc=0 execute every cycle.
Then what is the difference between these two codes?
function score() {
var sc = 0;
return function (correct) {
if (correct) sc++;
return sc;
}
}
var keepScore = score(); //here
function nextQuestion() {
var n = Math.floor(Math.random() * questions.length);
questions[n].displayQuestion();
var answer = prompt('Please select the correct answer.');
if (answer !== 'exit') {
questions[n].checkAnswer(parseInt(answer), keepScore); //here
nextQuestion();
}
}
2 Answers 2
Your function score is a function that returns a function. The outer function's variables are baked into the inner function (this is called a closure). The purpose of doing that here is to allow the variable sc to be used by the inner function but not be available to other functions. It is essentially a way to hide that variable. This is a common JavaScript idiom (you can use it in other languages, but I see it a lot more in JavaScript than in any other language—in fact, there's a related pattern given a special name: the immediately-invoked function expression).
The variable keepScore holds a reference to the function that score() returns, so when you call keepScore you are really calling that function. Since you only call score() once, sc is initialized to zero only once, and keepScore() increments it.
I have to wonder... if you don't know what it's doing, why did you write it that way?
2 Comments
This is because every time you run the score function you get a function returned that has a context with it (the variable sc) which gets initialized to zero for each call to score. When you call it once and keep the function in a variable, then you have one function that gets repeatedly called with one context and sc can increment.
You could get away without the variable if you pull the sc variable outside of the scope of the score function like this:
var sc = 0;
function score() {
return function(correct) {
if (correct) sc++;
return sc;
}
}
But then of course it begs the question - why bother with a function that returns a function at all? You could do this instead:
var sc = 0;
function score(correct) {
if (correct) sc++;
return sc;
}
// then later pass the function as a reference
questions[n].checkAnswer(parseInt(answer), score);