面向对象的JS - 没有全局变量?

时间:2011-10-01 05:38:58

标签: javascript oop

我正在采用面向对象的方法来构建Javascript应用程序。 首先,我正在创建一个Game对象和一个Timer对象。

这是我目前的实施: Timer对象具有以下方法:

setTimerValue()  
start()  
stop()  
getTimeLeft()  
timeExpired()

Game对象有以下方法:

reset()
run()
...

Timer.start()使用window.setInterval()开始倒计时。 当倒计时变为零时,它会调用Timer.timeExpired()

Timer.timeExpired()宣布游戏已结束,应致电Game.reset()Game.run()重启游戏。但是当Timer对象对游戏对象一无所知时怎么办?

游戏对象是否需要成为全局变量才能实现?

此外,Game对象当前有一个Timer对象作为其属性之一。这允许Game对象调用Timer方法。但不清楚Timer方法如何调用Game对象。

我怀疑我在对象之间创建了太多的依赖关系,并且可以使用一些关于如何更好地构建它的建议。

谢谢大家。

1 个答案:

答案 0 :(得分:4)

使用事件驱动方法或观察者设计模式。根据我的经验,Javascript具有灵活的事件驱动实现之一。 所以你有Timer对象,它实际上不需要知道任何其他对象。 当你调用Timer.start()时,对象应该发出一个自定义事件,比如“timerStarted”,同样对于其他方法:

Timer.stop() - > emits "timerStoped"
Timer.timeExpired() -> emits "timerExpired"

对于Timer引发的每个事件,应该有一个事件处理程序,当触发相应的事件时将调用它。

如果你使用jquery,处理事件应该是微不足道的:

var $ = jQuery.noConflict();
var timer = new Timer();
var game  = new Game();

$(timer).bind('timerStarted', function(e) {
    game.doSomething();
});
在Timer :: start()中你应该写:

start: function() {
    $(this).trigger('timerStarted');
}

另一种方法是使用回调: 如果你想在计时器启动时完成某些事情,你可以将lambda函数传递给计时器的start方法:

// timer method
start: function(callback) {
    if(typeof(callback) == 'function') {
        callback();
    }
}

// main logic
var timer = new Timer();
var game  = new Game();

timer.start(function() {
    game.doSomething();
});

我希望你能得到想法