Skip to content

Instantly share code, notes, and snippets.

@gordonbrander
Created March 5, 2012 18:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gordonbrander/1980280 to your computer and use it in GitHub Desktop.
Save gordonbrander/1980280 to your computer and use it in GitHub Desktop.
construct -- an alternate way to invoke constructor functions
// Bind another function as the `this` context for `construct` to create
// a method that will construct the given function and return the object
// directly, enabling immediate chaining.
//
// A bound version of `construct` can be thought of as a Functor, converting data in (the function)
// to a new kind of data out (the constructed object).
//
// Before:
//
// var f = new F();
// f.foo();
//
// After:
//
// var F = construct.bind(F);
// F().foo();
//
// Or use it to enforce `new` on constructors that support flexible arguments:
//
// var F = function () {
// if (!(this instanceof F)) return construct.apply(F, arguments);
// }
//
// You can also assign it to any function as an alternative function-based
// construction method that is compatible with `apply`:
//
// F.construct = construct;
// var f = F.construct(1, 2, 3);
var construct = function () {
var F = this,
// Create an object that prototypally inherits from the prototype of `F`.
// This is akin to calling `new F(...)`, but without invoking the
// function code in `F`.
self = Object.create(F.prototype);
self.constructor = F;
// Invoke the constructor function, passing our object to it. Between
// creating the object and invoking the constructor, you get essentially
// the same lifecycle as `new F(...)`. All this jiggery-pokery is to
// work around the fact that calling a function as a constructor with
// an array of arguments is hard.
F.apply(self, arguments);
return self;
};
@gordonbrander
Copy link
Author

A better solution than https://gist.github.com/1700841 to the problem of object construction via functions.

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