JS - closure, callback, immediate execution function expression simple implementation

Concept review

Closures: any internal function can always use the parameters and variables defined by its external function, even if the external function has successfully returned the end.

Callback: a callback function is a parameter (function pointer), which is passed to another function as a parameter, and only when the function is executed will the function passed in be executed. This process is called callback. Like an asynchronous process, this callback can be understood as Call it later.

Execute function expression immediately (IIFE): execute function expression immediately as the name implies, that is, the function is executed immediately, and it will be destroyed automatically after execution. Its advantage is scope isolation, that is, the variables and methods wrapped by the immediate function expression will not have any naming conflicts with the variables and methods outside the immediate function expression, which can encapsulate the code well and facilitate reuse.

code implementation

/*
 * Function Description:
 * A simple question and answer procedure, and score according to the answers,
 * If you are right, you will get one point. If you are wrong, you will not get one point. The problem will be randomly selected and prompt will be used
 * To submit the serial number of the answer to the question. After the answer is submitted, the current question result and the cumulative score will be obtained immediately
 * Then answer the next question. When you enter exit in prompt, the program ends.
 *
*/

/**
 * The whole code is wrapped by IIFE and isolated from the external scope
 */
(function(){

    var Question = function(qContent, answers, rightAnswerIdx){
        this.qContent = qContent;
        this.answers = answers;
        this.rightAnswerIdx = rightAnswerIdx;
    };

    Question.prototype.display = function(){
        console.log(this.qContent);
        for(var i=0; i<this.answers.length; i++){
            console.log(i + '.' + this.answers[i]);
        }
    };

    Question.prototype.displayScore = function(score){
        console.log('Current score:' + score);
        console.log('-----------------');
    };

    /**
     * Here we use the concept of callback function, the second parameter of checkAnswer method
     * callback Is an anonymous function returned for passing in the score method. sc defined here
     * Variable to hold the return value of the callback function.
     */
    Question.prototype.checkAnswer = function(answer, callback){
        var sc;
        if(answer === this.rightAnswerIdx){
            console.log("correct!");
            sc = callback(true);
        }else{
            console.log("Error!");
            sc = callback(false);
        }

        this.displayScore(sc);
    }

    /**
     * Here, the score() method uses the concept of closure, because the score() method returns
     * Another anonymous method, which is defined in the score() method
     * And even if the sc ore () function successfully returns the anonymous method, the
     * Anonymous methods can still use sc variables.
     */
    function score(){
        var sc = 0;
        return function(correct){
            if(correct){
                sc++;
            }
            return sc;
        }
    }
    var holdScore = score();

    /**
     * Creating three problem objects with construction method
     */
    var Q1 = new Question('What is your name??', ['Zhang San', 'Li Si', 'Cannabinoids'], 0);
    var Q2 = new Question('What is your gender?', ['male', 'female', 'manly woman'], 1);
    var Q3 = new Question('What is your dream?', ['To be the shadow of fire', 'The man who became the pirate king', 'Become Wang Feng'], 2);

    var QList = [Q1, Q2, Q3];

    /**
     * The recursive method is used to repeat the question, and only when the input
     * 'Exit 'before the program ends
     */
    function nextQuestion(){
        var randomNum = Math.floor(Math.random()*QList.length);
        QList[randomNum].display();

        var answer = prompt('Please enter the correct answer:');
        if(answer !== 'sign out'){
            QList[randomNum].checkAnswer(parseInt(answer), holdScore);
            nextQuestion()
        }
    }
    nextQuestion();

})();

Posted by plisken on Sun, 31 May 2020 00:06:52 -0700