Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created March 14, 2013 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XoseLluis/5162177 to your computer and use it in GitHub Desktop.
Save XoseLluis/5162177 to your computer and use it in GitHub Desktop.
Turn your JavaScript constructor functions into Singletons.
// deploytonenyures.blogspot.com
var singletonizer = {
singletonize: function(initialFunc){
if (typeof initialFunc != "function")
throw new TypeError("singletonizer.singletonize called on a non function");
//desingletonize works also as a flag to know if the function has been singletonized
if (initialFunc.desingletonize)
return initialFunc;
var instance;
function core(){
if (!instance){
//using aux to follow the "new" operator behaviour in case the constructor function returns a value
//we're passing arguments around, but indeed it does not make much sense to singletonize a function expecting parameters
var aux = initialFunc.apply(this, arguments);
instance = aux || this;
}
return instance;
};
//we're using the eval trick so that our singletonized function can keep the name of the original function, otherwise it would be empty
//eval runs in the current scope, so it traps "core" and "this" in the closure
eval ("var singletonizedFunc = function " + initialFunc.name + "(){"
+ "core.apply(this, arguments);"
+ "return this;"
+ "};");
singletonizedFunc.desingletonize = function(){
return initialFunc;
};
singletonizedFunc.prototype = initialFunc.prototype;
return singletonizedFunc;
},
desingletonize: function(func){
if (typeof func != "function")
throw new TypeError("singletonizer.desingletonize called on a non function");
return func.desingletonize ? func.desingletonize() : func;
}
};
if (typeof module !== "undefined" && module.exports){
exports.singletonizer = singletonizer;
}
if (typeof module !== "undefined"){
var singletonizer = require("./Singletonizer").singletonizer;
}
function NetworkManager(server){
console.log("NetworkManager constructor " + server);
this.creationTime = Date.now();
this.server = server;
}
var nm1 = new NetworkManager("server1");
console.log("- singletonize:");
singletonizedNM = singletonizer.singletonize(NetworkManager);
var nm2 = singletonizedNM("server2");
var nm3 = singletonizedNM("server3");
console.log ("nm2.creationTime == nm3.creationTime" + (nm2.creationTime == nm3.creationTime));
console.log("singletonizedNM.name: " + singletonizedNM.name);
console.log("- desingletonize:");
var desingletonizedNM = singletonizedNM.desingletonize();
var nm4 = desingletonizedNM("server4");
var nm5 = desingletonizedNM("server5");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment