So I'd like to have a class called client which will be the base of a video game I'm writing in JavaScript.
client should be a class that there can only be one instance of, but its first creation should be set by myself at a specific event, like when the user clicks the "start" button.
I made myself a singleton class and I'm starting it unload just for testing:
// Singleton class for the client
var client = (function() {
// Public methods
var _this = {
construct: function() {
delete _this.construct;
_this.director = new lime.Director(document.body, window.innerWidth, window.innerHeight); // Setup the rendering engine
}
}
return _this;
})();
// Fire when dependencies are loaded
window.onload = client.construct;
The problem:
But I intend for this to be an open source project and on the last line client.construct seems to be a highly unusual convention. How can I write my singleton class so that it will be constructed with new Client and can never be constructed again?
Firstly: are you sure you really want to do this? For most simple cases, you're probably better off not bothering with a prototype or using the new keyword at all, and instead just writing an object literal with the properties and methods you want - or creating an object with a one-off function if slightly more complicated construction logic is required. Simplicity is good.
I guess there are a couple of situations in which you might want to create a 'traditional' singleton in JavaScript, though - like to delay instantiation, or if you're using classical inheritance involving your singleton class's prototype.
In that case, you might want to try this approach, based upon bfavaretto's, in which the user of the class is expected to get a Client object by calling Client.getSingletonInstance() instead of new Client(), and the instantiation of a Client via new happens inside the getSingletonInstance() method.
var Client = (function() {
// Our "private" instance
var instance;
// The constructor
function Client() {
// If it's being called again, throw an error
if (typeof instance != "undefined") {
throw new Error("Client can only be instantiated once.");
}
// initialize here
// Keep a closured reference to the instance
instance = this;
}
// Add public methods to Client.prototype
Client.prototype.myPublic = function() {
}
Client.getSingletonInstance = function() {
if (typeof instance == "undefined") {
return new this();
}
else {
return instance;
}
}
// Return the constructor
return Client;
})();
var c1 = Client.getSingletonInstance();
var c2 = Client.getSingletonInstance();
console.log(c1 == c2); // true
I prefer this way, because it seems to me that having the user of the class call new but not actually get a new object is misleading.
http://jsfiddle.net/hBvSZ/3/
You can use the same pattern you would use in a regular object-oriented language: store the instance in a "private" or "static" property (I'm quoting those terms because they don't precisely apply to JavaScript). In code, that would be something like this, using a "private" property to store the instance (a "static" property would be a property of the constructor):
var Client = (function() {
// Our "private" instance
var instance;
// The constructor
function Client() {
// If it's being called again, return the singleton instance
if(typeof instance != "undefined") return instance;
// initialize here
// Keep a closured reference to the instance
instance = this;
}
// Add public methods to Client.prototype
Client.prototype.myPublic = function() {
}
// Return the constructor
return Client;
})();
var c1 = new Client();
var c2 = new Client();
console.log(c1 == c2); // true
http://jsfiddle.net/hBvSZ/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With