我的JavaScript范围有什么问题?

这个问题在这里已经有了答案:

  • JavaScript关闭如何工作? 88个答案
  • 循环中的JavaScript闭包 - 简单实用的例子35个答案

  • Javascript有功能范围。 这意味着

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

    相当于

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

    事实上,这是JavaScript编译器如何处理这些代码。 当然,这会导致你的小技巧失败,因为在setTimeout的函数被调用之前, j将会增加,即j现在不会做任何与i不同的任何事情,它只是一个具有相同范围的别名。

    如果Javascript有块范围,你的技巧就可以工作,因为j在每次迭代中都是一个新变量。

    你需要做的是创建一个新的范围:

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

    IIFE的替代方案是一个功能工厂:

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

    这就是说,这是javascript标签中最常见的问题之一。 看到:

  • 循环内的JavaScript闭包 - 一个简单实用的例子
  • Javascript臭名昭着的循环问题?

  • 另一种方法是使用(通常被滥用)的关键字with

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

    它创建了一个像函数一样的新范围,但没有尴尬的语法。 我第一次在这里看到它:JavaScript的“with”声明是否有合法用途?

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

    上一篇: What is wrong with my javascript scope?

    下一篇: Awkward way of executing JavaScript code