将范围从全局更改为本地突破Javascript程序

时间:2014-06-15 04:49:18

标签: javascript function scope lexical-scope

感谢你们精通Overflowians的帮助,我修复了我那个愚蠢的小RNG Addition游戏并让它运转起来。现在,根据一个用户的建议,在我编写下一个游戏之前,我正试图将添加游戏代码的范围从全局更改为本地;我希望每个游戏都完全包含在自己的范围内,因为我理解学习不会轻率地污染全球范围是一个好主意。但是,我对如何实现这一点感到有点困惑。

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

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上提供了功能代码。

1 个答案:

答案 0 :(得分:1)

请注意,JSFiddle中的onLoad选项与第二个代码段相同。当您自己绑定到No wrap时,您会想要选择'load'个选项之一。

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

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

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

当事件已经触发并处理外部绑定时,为它添加更多处理程序为时已晚。它们不会循环通过,事件不应再发生。

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

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

    initChallenge();
});

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

(function () {
    // ...

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