简体   繁体   中英

Object-Oriented JS - without global variables?

I am taking an object-oriented approach to building a Javascript app. For starters, I am creating a Game object and a Timer object.

Here's my current implementation: The Timer object has the following methods:

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

The Game object has the following methods:

reset()
run()
...

Timer.start() uses window.setInterval() to start the countdown. When the countdown gets to zero, it calls Timer.timeExpired() .

Timer.timeExpired() announces that the game is over and should call Game.reset() and Game.run() to restart the game. But how can this be done when the Timer object doesn't know anything about the Game object?

Does the Game object need to be a global variable for this to work?

Also, the Game object currently has a Timer object as one of its properties. This allows the Game object to call the Timer methods. But unclear on how Timer methods can call the Game object.

I have a nagging suspicion that I am creating too many dependencies between the objects and could use some suggestions on how to architect this better.

Thanks everyone.

Use an event driven approach or the observer design pattern. Javascript has one of the flexible event driven implementation from my experience. So you have the Timer object which doesn't really have to know about any other objects. When you call Timer.start(), the object should emit a custom event, like "timerStarted", likewise for the other methods:

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

For every event raised by the Timer, there should be an event handler, which will be called when the coresponding event is fired.

If you use jquery, handling events should be trivial:

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

$(timer).bind('timerStarted', function(e) {
    game.doSomething();
});

in the Timer::start() you should write:

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

Another approach is using callbacks: If you want something to be done when the timer starts, you could pass a lambda function to the start method of the timer:

// 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();
});

I hope you get the ideea

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM