0

So I'm new to javascript and I am looking for a way to count how many times a function is executed. The code randomly generates a square or circle and displays from the shape is shown to when you click it (reactionTime). That works fine and dandy. But I'm looking for a way to keep track of the number of times a shape is clicked and then eventually the cumulative time to calculate average time per click. If it helps, I come from a pretty good C++ background.

To count number of clicks, I was thinking of adding a closure function. From here: How do I find out how many times a function is called with javascript/jquery?

    myFunction = (function(){
        var count = 0;
        return function(){
            count++
            alert( "I have been called " + count + " times");
        }
     })();

And from here: Function count calls

    var increment = function() {
        var i = 0;
        return function() { return i += 1; };
    };

    var ob = increment();

But I tried a global variable and several variations of closure functions to no avail (look for the comments). I tried putting the closure function in other functions. And I also tried something like:

    var increment = makeBox();

I'm wondering if anyone can guide me in the right direction. It would be much appreciated!

    var clickedTime; var createdTime; var reactionTime;

    var clicked; var avg = 0;

    avg = (avg + reactionTime) / clicked;
    document.getElementById("clicked").innerHTML = clicked;
    document.getElementById("avg").innerHTML = avg;

    function getRandomColor() {
    ....
    }

    function makeBox() { // This is the long function that makes box
        createdTime = Date.now();
        var time = Math.random();
        time = time * 3000;

        ///////// var increment = function () {
            var i = 0;
            //return function() { return i += 1; };
            i++;
            return i;
        ///////// };


        // clicked++; /////////// global variable returns NaN
        // console.log(clicked);
        // alert("Clicked: "+clicked);

        setTimeout(function() {
            if (Math.random() > 0.5) {
                document.getElementById("box").style.borderRadius="75px"; }
            else {
                document.getElementById("box").style.borderRadius="0px"; }

            var top = Math.random(); top = top * 300;
            var left = Math.random(); left = left * 500;

            document.getElementById("box").style.top = top+"px";
            document.getElementById("box").style.left = left+"px";
            document.getElementById("box").style.backgroundColor = getRandomColor();
            document.getElementById("box").style.display = "block";
            createdTime = Date.now();
        }, time);
    }

    ob = increment(); //////////////////////// I think this gives me 1 every time
    alert("Increment: "+ob); //////////////////

    document.getElementById("box").onclick = function() {
        clickedTime = Date.now();
        reactionTime= (clickedTime - createdTime)/1000;
        document.getElementById("time").innerHTML = reactionTime;
        this.style.display = "none";
        makeBox();
    }

    makeBox();
3
  • At least the count++ in the first block is missing a semicolon. Commented Aug 23, 2015 at 18:32
  • @Roope It's not needed Commented Aug 23, 2015 at 18:33
  • @DenysSéguret good to know! Commented Aug 23, 2015 at 18:34

3 Answers 3

2

You have a few problems but to answer your question:

  • You're not defining clicked as a number (or any other type) so trying to perform an operation on undefined returns NaN...because well, it's not a number.
  • Your second attempt var i = 0; won't work because i is re-defined on each function call.

You should be able to use your gobal variable clicked as long as you set it to zero.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is an example that shows how a closure can count calls to a function:

function add5(y) {
    //A totally normal function
    return y + 5;
}

var counter = 0, /*a counter scoped outside of the function counter function*/
    trackedAdd5 = (function (func) {
        /*This anonymous function is incrementing a counter and then calling the function it is passed*/
        return function () {
            counter++;
            /*The trick is this function returns the output of calling the passed in function (not that it is applying it by passing in the arguments)*/
            return func.apply(this, arguments);
        }
    })(add5); /*calling this tracking function by passing the function to track*/

document.getElementById('run').addEventListener('click', function () {
    /*Here we are treating this new trackedAdd5 as a normal function*/
    var y = document.getElementById('y');
    y.value = trackedAdd5(parseInt(y.value, 10));
    /*Except the outer counter variable now represents the number of times this function has been called*/
    document.getElementById('counter').value = counter;
});
<label> <code>y = </code> 
    <input id='y' value='0' />
    <button id='run'>add5</button>
</label>
<br/>
<label><code>add5()</code> was called
    <input readonly id='counter' value='0' />times</label>

1 Comment

thanks! i'll try that and see what happens. closure functions are confusing
0
makeBox.click = 0; // define the function's counter outside the function
makeBox.click++; // replace the `i` usage with this inside the function

About ob = increment();: it is used erroneously (redefines ob many times);

var ob = increment(); // define it once
ob(); // increments the counter

// another way to define `increment`:
var increment = (function () {
    var i = 0;
    return function () {
        return i += 1;
    };
})();

ob = increment(); // ob becomes 1 initially
ob = increment(); // ob becomes 2, etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.