【问题标题】:Why does commenting out the alert() line of this code make it fail?为什么注释掉此代码的 alert() 行会使其失败?
【发布时间】:2011-01-28 03:12:24
【问题描述】:

我对 javascript 有一个非常奇怪的问题。如果您使用下面的代码并运行它,它将运行良好而没有任何错误,但是如果您注释第一个 alert,它将在第 5 行 (var _board = Bomber.BoardFactory.getBoard();) 抛出错误,说 BoardFactory 不存在(请记住第一次警报时,一切都在正常运行)。我已经能够使用 Firefox 和 Chrome 重现这种确切的行为。

Bomber = {};

Bomber.Game = function () {
    var self = {};
    var _board = Bomber.BoardFactory.getBoard();

    self.init = function () {};
    self.start = function () {};

    return self;
}

alert("2");

(function () {
    var instance;

    Bomber.BoardFactory = {};
    Bomber.BoardFactory.getBoard = function () {
        if (!instance)
            instance = new Bomber.Board();
        return instance;
    };
})();

alert("3");

Bomber.Board = function () {
    var self = {};
    return self;
}

$(document).ready(function () {
    var game = Bomber.Game();
    game.init();
    game.start();
});

我的问题是什么可能导致这种奇怪的行为?到底怎么可能一个警报调用让它识别Bomber.BoardFactory

【问题讨论】:

    标签: javascript jquery closures hoisting


    【解决方案1】:

    我通过 jslint 运行它,修复了错误(if 中缺少 2 个分号和缺少 {})

    现在好像可以了

    Bomber = {};
    
    Bomber.Game = function () {
        var self = {};
        var _board = Bomber.BoardFactory.getBoard();
    
        self.init = function () {};
        self.start = function () {};
    
        return self;
    };
    
    //alert("2");
    
    (function () {
        var instance;
    
        Bomber.BoardFactory = {};
        Bomber.BoardFactory.getBoard = function () {
            if (!instance){
                instance = new Bomber.Board();
            }
            return instance;
        };
    })();
    
    //alert("3");
    
    Bomber.Board = function () {
        var self = {};
        return self;
    };
    
    $(document).ready(function () {
        var game = Bomber.Game();
        game.init();
        game.start();
    });
    

    发生的情况是你在定义 Bomber.Game 后缺少最后一个分号,所以接下来是 (function()..etc,所以它认为你正在调用该函数。

    如果您有警报,您将通过自动分号插入保存。

    【讨论】:

    • @HoLyVieR 只是第一次看到它 :-) 我不使用分号,除非需要 - 但是,对于以 ( 开头的表达式,(或很少使用 @987654324 @ 还有+-)我总是在它们前面加上;,例如:;(function () {...})()。 JavaScript 确实使用了 ASI,但它如果前面的表达式可以继续,它不会放入分号。由于...}\nalert(... 不是一个有效的表达式,JavaScript 将其读取为...};alert(...。编码愉快。
    • @pst 分号被插入在函数的结束 } 和以 alert 开头的行之间(据我了解)
    • @david 是的,我读错了——删除了评论:) 好答案。
    • @pst 把分号放进去总是比试图玩弄系统更安全。如果您担心大小,请通过优化器/编译器运行它,它会删除您不需要的分号。
    • @pst 真的吗?为什么要冒随机错误的风险?我把它放在任何地方它需要的地方,以防万一。我不相信分号插入。
    【解决方案2】:

    很难预测哪个会先执行:(function () {$(document).ready(function () { 尝试将它们结合起来并在其他任何事情之前声明所有函数

    【讨论】:

    • 不,不是,立即执行的函数总是先执行。
    • 不是在这种情况下,Bomber.BoardFactory 在调用 Bomber.Game() 时未定义
    • 这是因为对 Bomber.Game() 的调用没有在 $(document).ready 处理程序中发生,它是立即发生的,因为 OP 省略了分号。
    • 对,我现在记得混淆是在 $(document).ready(function () { 和 function pageLoad() { 不要被误认为是自执行函数,对不起,我的错误
    猜你喜欢
    • 2021-09-17
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2017-02-28
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多