1

For the code below, I am getting the following error on the second line of the GameStatsPanel function:

"Uncaught TypeError: Object #Timer has no method 'start'"

I'm really quite confused why this is happening - I have a feeling I'm missing something simple somewhere but I need enlightened. Feel free to check out the issue by going to www.letsplayglobalgames.com and selecting the 'Play!' option from the homepage. Let me know if you need more details.

function GameStatsPanel() {
    this.timer = new Timer();
    this.timer.start(); /* error is thrown here */
}
function Timer() {
    this.container = document.getElementById('game_time');
    this.current_flag_time_start;
    this.current_flag_time_stop;
    this.time_start = new Date();
    this.time_stop;
    this.time_difference;
    this.current_flag_time_difference;
}
Timer.prototype.start = function() {
    this.current_flag_time_start = new Date();
}
2
  • Did you create the object like new GameStatsPanel() Commented Feb 21, 2013 at 6:14
  • Yes, I have the code: gameStatsPanel = new GameStatsPanel(); Commented Feb 21, 2013 at 6:22

1 Answer 1

3

You're invoking the Timer constructor before the Timer.prototype has a chance to be set up with your methods.

The Timer function is available, because function declarations are "hoisted", and therefore available immediately.

The extensions to Timer.prototype are not "hoisted", so your Timer has an unmodified .prototype when you do new Timer.

gameStatsPanel = new GameStatsPanel(); // Invoking this too soon. Put it and
// ...                            // anything else that uses the constructors at
                                  // the bottom so the prototypes can be set up.
function main() {
   // ...
}

function GameStatsPanel() {
    this.timer = new Timer(); // The `Timer.prototype` extensions haven't run yet
    // ...
    this.timer.start(); // .start doesn't yet exist
}

// ...

function Timer() {
    // ...
}

// ...

 // *Now* the .start() method is getting added.
Timer.prototype.start = function () {
    this.current_flag_time_start = new Date();
}

// ...
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the response but I'm still slightly confused. After looking some more info up on hoisting, I understand the concept but not how it applies here to the prototype functions. Can you give some more details or recommend an example for fixing the issue?
@LetsPlayGlobalGames: The function declarations are hoisted. That means it's as though you wrote the Timer and GameStatsPanel functions at the top of the file. The rest of the stuff doesn't move. So taking the code in my answer above, imagine those two functions at the top. Then below that you do gameStatsPanel = new GameStatsPanel();. This invokes the GameStatesPanel function, which invokes Timer, creating a new Timer instance. The Timer instance then calls its .start() method. Trouble is that all of this has happened at the invocation of GameStatsPanel(), which is...
...located before the Timer.prototype.start = func... line. This means you're trying to invoke .start() before it exists. This code may help show it. The .start() doesn't work, but if you move it higher up before the constructors are invoked, it'll then work, like this.
...basically, make sure none of your functions are invoked until they're fully set up.
ahhhh, got it. Not sure I like that though... reminds me of C coding where order/placement on functions in a file matters. Thanks for the response and thanks for taking the time to throw the code in JSFiddle. Much appreciated!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.