javascript - click 函数中的 var 变得未定义

标签 javascript jquery

我正在构建一个基于 javascript 的游戏,其 map 分为多个区域。对于每个区域,游戏都会检查某些条件,如果满足这些条件,则会向该区域添加点击功能。这会产生以下代码:

for (var ter = 0; ter < territoryStateInfo.length; ter++) {
    for (var adjacent = 0; adjacent < territoryStateInfo[ter].adjacentTer.length; adjacent++) {
        var tempAdjID = territoryStateInfo[ter].adjacentTer[adjacent];
        if (/*long if statement*/) {
            console.log(ter);
            $('#territoryArea' + ter).addClass('viableTarget');
            $('#territoryArea' + ter).click(function(){
                console.log(ter);
                applyNH(ter);
                for (var ter = 0; ter < territoryStateInfo.length; ter++) {
                    $('#territoryArea' + ter).removeClass('viableTarget');
                }
            });
            break;
        }
    }
}

出于某种原因,第一个控制台日志按预期报告了变量“ter”。然而,一旦通过单击相应的区域记录完全相同的术语,它就会返回一个未定义的值。我的第一个想法是,ter 的值将在我单击区域时确定(即循环结束且变量不再存在之后),而不是创建单击函数时的值。然而,在我看来这不太可能,因为我有另一段代码的工作原理与此类似,但没有给出未定义的值。示例如下:

var viableUtilityTargets = [];
for (var ter = 0; ter < territoryStateInfo.length; ter++) {
    for (var unit = 0; unit < territoryStateInfo[ter].occupiedByUnits.length; unit++) {
        if (/*another long ramble*/) {
            if ($('#territoryArea' + ter).hasClass !== 'viableTarget') {
                $('#territoryArea' + ter).addClass('viableTarget');
                $('#territoryArea' + ter).click(function(){
                    console.log(ter);
                    applyUtility(ter, viableUtilityTargets);
                });
            }
            viableUtilityTargets.push(territoryStateInfo[ter].occupiedByUnits[unit]);
        }
    }
}

有人能弄清楚为什么这个变量会这样起作用以及我该如何解决这个问题吗? 预先感谢您!

最佳答案

更改此:

$('#territoryArea' + ter).click(function(){
    console.log(ter);
    applyUtility(ter, viableUtilityTargets);
});

对此:

$('#territoryArea' + ter).click(
    (function(ter){
        return function() {
            console.log(ter);
            applyUtility(ter, viableUtilityTargets);
        };
    })(ter)
);

将代码包装在IIFE中(I立即I调用F函数Expression) 将为每次迭代创建一个新的范围。外部 ter 被传递到 IIFE 以将其设置为内部 ter,该内部 ter 在定义事件监听器函数的范围内是唯一的。在您的代码中,所有事件监听器都将引用相同的 ter,然后使用 for 循环递增该引用,直到它变为 territoryStateInfo.length ,因此当单击发生时,无论单击哪个按钮,事件监听器内的 ter 都将是长度 => for 循环会弄乱闭包,因为它在整个事件中保持相同的范围整个迭代,因此依赖于该作用域的所有函数都将引用在该作用域(for 循环所在函数的作用域)内创建的相同变量,最糟糕的是原始作用域中的这些变量不断变化(即使在循环之后)

关于javascript - click 函数中的 var 变得未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42847045/

相关文章:

javascript - 网络音频 api 音量指示器 - 不再有声音

javascript - 媒体查询和 javascript 不能很好地结合在一起

javascript - 根据if条件选择ajax url

javascript - jQuery 日期选择器 UI 工具提示

javascript - Html POST 并返回与值相同的形式

javascript - 使用 Ajax 调用上传大文件

javascript - 有没有办法使某些组件(即 <div>)在网页上自动滚动?

javascript - 限制表单中选中的复选框

javascript - 用户单击链接时如何在新选项卡中打开链接

javascript - 未加载动态添加的 CSS 文件