Best way to combine the module pattern with closures
closures, design-patterns, javascript
Solution
First off, to access the `update` function in that fashion it will have to exposed in the returned object.
return {
update: function() {
[...]
},
startGame: function() {
[...]
this.update();
}
}
Calling `obj.method()` automatically sets the `this` reference inside this `method` call to `obj`. That is, calling `MYAPP.game.startGame()` sets `this` to `MYAPP.game` inside this `startGame` method call. More details about this behavior here.
You will also want to move the `lives` variable to a common scope which is accessible by both `startGame` and `update` methods, which is exactly what the closure is for:
MYAPP.game = (function() {
[...]
var lives; //private/privileged var inside the closure, only accessible by
//the returned object's function properties
return {
update: function() {
utils.fn1(lives);
},
startGame: function() {
[...]
lives = 3; //sets the closure scope's lives variable
[...]
this.update();
}
}
})();
Fiddle
In this case you will need some method to set the `lives` variable when you want to change it. Another way would be to make the `lives` variable public as well by making it a property of the returned object and accessing it through `this.lives` inside of the methods.
NOTE: If you simply pass a reference to the function object stored as property of the returned object as in:
$('#button').on('click', MYAPP.game.update);
The `this` reference inside the click handler will not point to `MYAPP.game` as the function reference that has been passed will be called directly from the jQuery core instead of as an object's member function call - in this case, `this` would point to the `#button` element as jQuery event handlers set the `this` reference to the element that triggered the handler, as you can see here.
To remedy that you can use `Function.bind()`:
$('#button').on('click', MYAPP.game.update.bind(MYAPP.game));
Or the old function wrapper trick:
$('#button').on('click', function() {
MYAPP.game.update(); //called as method of an obj, sets `this` to MYAPP.game
});
This is important when the `this` keyword is used inside the `update` method.
Problem
I'm currently trying to implement some common JS concepts in little projects to understand better how to use them. I've been working on a simple game, trying to understand and use the module pattern and closures. I'm using the module pattern from Stoyan Stefanov's 'patterns' book. I'm struggling to understand how best to mix modules and closures. I'd like to know if I'm organising the following code in a sensible way? If so, my question is: what's the best way to modify the code so that in the `$(function(){})` I have access to the `update()` function? ``` MYAPP.utilities = (function() { return { fn1: function(lives) { //do stuff } } })(); MYAPP.game = (function() { //dependencies utils = MYAPP.utilities return { startGame: function() { //initialisation code //game state, stored in closure var lives = 3; var victoryPoints = 0; function update(){ utils.fn1(lives); //do other stuff } } } })(); $(function(){ MYAPP.game.startGame(); //Want to do this, but it won't work //because I don't have access to update $('#button').on('click',MYAPP.game.update) }); ``` I've come up with a couple of options which would work, but I'd like to know if they're good practice, and what the best option is. Options: (1) Bind `$('#button').on('click', ...)` as part of the startGame initialisation code. (2) Assign the `update()` function to a variable, and return this variable from the startGame function, So in `$(function(){})` we could have `updatefn = MYAPP.game.startGame();` and then `$('#button').on('click',MYAPP.game.update)` (3)? Is there a better way? Thank you very much for any help, Robin