Skip to content

Instantly share code, notes, and snippets.

@cowboy
Last active July 8, 2018 03:23
Show Gist options
  • Save cowboy/a306010646ccb16e0038 to your computer and use it in GitHub Desktop.
Save cowboy/a306010646ccb16e0038 to your computer and use it in GitHub Desktop.
JavaScript: Constructor returning a "function" instance.
var util = require("util");
function Thing() {
// The instance is also a proxy function for its __default method.
var instance = function() {
return instance.__default.apply(instance, arguments);
};
// The instance needs to inherit from Thing.prototype.
instance.__proto__ = Thing.prototype;
// Initialize the instance with the __ctor method.
instance.__ctor.apply(instance, arguments);
// The instance must be returned!
return instance;
}
// All "instances" of Thing need to inherit from Function, as they are
// functions!
util.inherits(Thing, Function);
// Used to initialize each new Thing instance.
Thing.prototype.__ctor = function(options) {
this.value = options.value;
};
// Used when each Thing instance is invoked.
Thing.prototype.__default = function(value) {
this.value = value;
return value;
};
// One of many possible methods.
Thing.prototype.getValue = function() {
return this.value;
};
var thing = new Thing({value: "initial"});
console.log(thing.getValue()); // "initial"
console.log(thing("changed")); // "changed"
console.log(thing.getValue()); // "changed"
thing.value = "changed again";
console.log(thing.getValue()); // "changed again"
@cowboy
Copy link
Author

cowboy commented May 12, 2015

The idea for this is to be able to create instances of what's currently a singleton pattern, where the "namespace object" is a function and not a plain object, like:

var thing = function() {
 // do something
};

thing.method = function() {
 // do something else
};

module.exports = thing;

Another alternative would be to throw everything in a factory function, like so:

exports.makeThing = function() {
  var thing = function() {
   // do something
  };

  thing.method = function() {
   // do something else
  };

  return thing;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment