What is wrong with my javascript scope?

This question already has an answer here:

  • How do JavaScript closures work? 88 answers
  • JavaScript closure inside loops – simple practical example 36 answers

  • Javascript has function scope. This means that

    for(...) {
        var j = i;
    }
    

    is equivalent to

    var j;
    for(...) {
        j = i;
    }
    

    In fact, this is how Javascript compilers will actually treat this code. And, of course, this causes your little "trick" to fail, because j will be incremented before the function in setTimeout gets called, ie j now doesn't really do anything different than i , it's just an alias with the same scope.

    If Javascript were to have block scope, your trick would work, because j would be a new variable within every iteration.

    What you need to do is create a new scope:

    for(var i = ...) {
        (function (j) {
            // you can safely use j here now
            setTimeout(...);
        })(i);
    }
    

    The alternative the the IIFE is a function factory:

    function timer() {
        for (var i = 0; i < 3; ++i) {
            setTimeout(createTimerCallback(i), 1000);
        }
    }
    
    function createTimerCallback(i) {
        return function() {
           alert(i);
        };
    }
    
    timer();
    

    This being said, this is one of the most asked questions in the javascript tag. See:

  • JavaScript closure inside loops – simple practical example
  • Javascript infamous Loop issue?

  • An alternative is to use the (normally abused) keyword with :

    function timer() {
        for (var i = 0; i < 3; ++i) {
            with({j: i}) {
                setTimeout(function () {
                    alert(j);
                }, 1000);
            }
        }
    }
    
    timer();
    

    It creates a new scope like functions do, but without the awkward syntax. I first saw it here: Are there legitimate uses for JavaScript's “with” statement?

    链接地址: http://www.djcxy.com/p/83008.html

    上一篇: 被JavaScript中的闭包困惑

    下一篇: 我的JavaScript范围有什么问题?