【问题标题】:Javascript Closure functionsJavascript 闭包函数
【发布时间】:2015-08-24 03:13:46
【问题描述】:

所以我是 javascript 新手,我正在寻找一种计算函数执行次数的方法。代码随机生成一个正方形或圆形,并从形状显示到单击它时显示(reactionTime)。这工作得很好,花花公子。 但我正在寻找一种方法来跟踪单击形状的次数,然后最终计算累积时间来计算每次点击的平均时间。如果它有帮助,我来自非常好的 C++ 背景。

为了计算点击次数,我正在考虑添加一个闭包函数。 从这里: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");
        }
     })();

从这里开始:Function count calls

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

    var ob = increment();

但我尝试了一个全局变量和几个闭包函数的变体,但无济于事(寻找 cmets)。我尝试将闭包函数放在其他函数中。我还尝试了类似的方法:

    var increment = makeBox();

我想知道是否有人可以指导我正确的方向。将不胜感激!

    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();

【问题讨论】:

  • 至少第一个块中的count++ 缺少分号。
  • @Roope 不需要
  • @DenysSéguret 很高兴知道!

标签: javascript function closures


【解决方案1】:

您有一些问题,但要回答您的问题:

  • 您没有将clicked 定义为数字(或任何其他类型),因此尝试对undefined 执行操作会返回NaN...因为它不是数字。
  • 您的第二次尝试 var i = 0; 将不起作用,因为 i 在每个函数调用中都重新定义。

只要将全局变量clicked 设置为零,您就应该能够使用它。

【讨论】:

    【解决方案2】:

    下面是一个例子,展示了闭包如何计算对函数的调用:

    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>

    【讨论】:

    • 谢谢!我会试试看,看看会发生什么。闭包函数令人困惑
    【解决方案3】:
    makeBox.click = 0; // define the function's counter outside the function
    makeBox.click++; // replace the `i` usage with this inside the function
    

    关于ob = increment();:被错误使用(多次重新定义ob);

    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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 2017-01-11
      • 2015-12-03
      • 2013-07-10
      • 2011-05-27
      • 2010-09-19
      相关资源
      最近更新 更多