Skip to content
mckoss edited this page Apr 27, 2011 · 17 revisions

funcs.js - basic extension for JavaScript functions

See source code

patch()

funcs.js does not modify the global Function object unless you call the patch function:

var funcs = require('org.startpad.funcs').patch();

When you do so the following methods are added to the global Function.prototype:

  • func.methods(methodsObject)
  • func.curry(args, ...)
  • func.curryThis(this, args, ...)
  • func.decorate(decoratorFunction)
  • func.subclass(superClass, extraMethods)

If you do not want to modify the global Function object, you can reach these methods via exported functions of the org.startpad.funcs namespace.

function.methods(methodsObject)

Also funcs.methods(function, methodsObject)

Copies the named methods from the methodsObject into the given function.prototype (usually a constructor function).

function.curry(args, ...)

Also funcs.bind(function, undefined, args, ...)

Return a closure where the this value, and optional arguments are pre-bound to the function arguments. Note that any args passed as undefined will be filled in by the arguments sent my the caller. For example:

function test(a, b, c) {
    console.log(a, b, c);
}

var bound = test.curry(1, undefined, 2);  // or funcs.bind(test, undefined, 1, undefined, 2)
bound(3);  // 1, 3, 2

function.curryThis(this, args, ...)

Also funcs.bind(function, this, args, ...)

Also binds the this variable in addition to (optional) arguments.

function.subclass(superClass, methodsObject)

Also funcs.subclass(constructor, superClass, methodsObject)

Inherit methods from the superClass, and optionally add your own methods to your constructor. Usage:

function SuperClass() {
    ...
}

SuperClass.methods({
    myFunction: function () {
    ...
    }
});

function SubClass() {
    SuperClass.call(this);  // Call SuperClass constructor
    ...
}

SubClass.subclass(SuperClass, {
    myFunction: function () {
        SuperClass.prototype.myFunction.call(this);  // Call SuperClass's myFunction
        ...
    }
});

function.mro(superClasses, objectMethods)

Also funcs.mro(classList, objectMethods)

Implements an explicit Method Resolution Order to implement multiple inheritance. A custom prototype chain is set up in the order of the classes provided in the first array parameter.

You can call a parent class constructor via:

function SubClass() {
    this.SubClass_super.constructor.call(this, args);
}

You can call a parent class method via:

SubClass.methods({
    method: function () {
        this.SubClass_super.method.call(this, args);
    }
});

function.decorate(decorator)

Also funcs.decorate(function, decorator)

A decorator function can be used to modify the behavior of any other function in a standardized way. A decorator is a function with the following function signature:

decorator(function, arguments, wrapper)

where:

  • this - The this value from the caller (or the function being wrapped during initialization).
  • function - The function being wrapped by the decorator (undefined when decorator is being initialized).
  • arguments - An arguments object for all the arguments of the function call.
  • wrapper - A closure function created when the decorator is applied.

To wrap a function in a decorator:

function anyFunction() {...}

var wrappedFunction = anyFunction.decorate(decorator);

The decorator will be called once to initialize itself, if needed. A template for writing a decorator is:

function countCalls(fn, args, decorated) {
    if (fn == undefined) {
        decorated.count = 0;
        return;
    }
    decorated.count++;
    return fn.apply(this, args);
}

funcs.create(obj)

Return an object whose __proto__ property is set to the passed in object (prototypical inheritance). The implementation is the same as Object.create if available.

funcs.monkeyPatch(function, byString, versionString, patchMethods)

Copy the names methods from patchMethods onto the function's prototype ("monkey patching" the methods onto it). Pass in a "by" string to indicate "who" is doing the patching (e.g., 'org.startpad.myprogram'), and a 3-part version string (e.g., '1.0.3'). The monkeyPatch will do nothing if the function has already been patched by an equal or greater version of your program.