【问题标题】:Changing Scope from Global to Local Breaking Javascript Program将范围从全局更改为本地破坏 Javascript 程序
【发布时间】:2014-06-15 04:49:17
【问题描述】:

感谢你们优秀的溢出者的帮助,我修复了我那愚蠢的小 RNG 加法游戏并让它运行起来。现在,根据一位用户的建议,在编写下一个游戏之前,我正在尝试将添加游戏代码的范围从全局更改为本地;我希望每个游戏都完全包含在自己的范围内,因为我知道学习不要轻率地污染全局范围是一个好主意。但是,我对如何实现这一点有点困惑。

这是当前功能加法游戏的代码:

function beginAdditionChallenge() {
    var x = Math.ceil(Math.random()*100);
    alert(x);
    for (var i = 0; i < 3; i++) {
        var a = Number(prompt("Provide the first addend.", ""));
        var b = Number(prompt("Provide the second addend.", ""));
        if (a + b === x) {
            alert("Well done!");
            break;
        }
            else if (a + b !== x && i < 2) {
            alert("Please try again.");
        }
        else {
            alert("Derp.");
        }
    }
}

function initChallenge() {
    var button = document.getElementById("challengeButton");
    button.addEventListener("click", beginAdditionChallenge);
}

window.addEventListener("load", initChallenge);

这是我尝试包装它的尝试,它只成功地破坏了游戏,以至于按钮甚至没有响应:

window.addEventListener("load", function() {
    function beginAdditionChallenge() {
        var x = Math.ceil(Math.random()*100);
        alert(x);
        for (var i = 0; i < 3; i++) {
            var a = Number(prompt("Provide the first addend.", ""));
            var b = Number(prompt("Provide the second addend.", ""));
            if (a + b === x) {
                alert("Well done!");
                break;
            }
                else if (a + b !== x && i < 2) {
                alert("Please try again.");
            }
                else {
                alert("Derp.");
            }
        }
    }

    function initChallenge() {
        var button = document.getElementById("challengeButton");
        button.addEventListener("click", beginAdditionChallenge);
    }

    window.addEventListener("load", initChallenge);
    });

功能代码在 JSFiddle here 上可用。

【问题讨论】:

  • 你可以对本地上下文使用自调用函数,它也不会破坏你的代码。
  • 你只需要学习如何使用小提琴...何时关闭onLoad设置

标签: javascript function scope lexical-scope


【解决方案1】:

请注意,JSFiddle 中的onLoad 选项与您的第二个 sn-p 相同。当您自己绑定到'load' 时,您需要选择No wrap 选项之一。

而且,问题源于尝试在 'load' 处理程序中绑定到 'load'

window.addEventListener("load", function() {
    // ...

    window.addEventListener("load", initChallenge);
});

当事件已经触发并处理外部绑定时,再添加更多的处理程序已经太迟了。它们不会被循环,并且事件不应再次发生。

你要么想在外部事件绑定中调用initChallenge

window.addEventListener("load", function() {
    // ...

    initChallenge();
});

或者,您可以使用带有内部绑定的IIFE

(function () {
    // ...

    window.addEventListener("load", initChallenge);
})();

【讨论】:

  • 在这两种解决方案中,有什么特别的理由偏爱其中一种吗?
  • @user242007 不是真的。外部绑定将为您的代码提供与 IIFE 相同的本地范围。这只是个人喜好问题。
  • 使用了 IIFE 方法,它再次运行。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2015-09-30
  • 2021-03-05
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-06
  • 1970-01-01
  • 2012-08-09
相关资源
最近更新 更多