proto

prototypeMethods

declaration
 prototypeMethods 

var prototypeMethods = module.exports = {
    extendProto: extendProto,
    createSubclass: createSubclass,
    makeSubclass: makeSubclass,
    newApply: newApply
};


var __ = require('./proto_object');

__.extend.call(__, require('./proto_function'));

extendProto

function
 extendProto() 

Option name Type Description
self Function

constructor function

methods Object

a map of functions, keys will be instance methods (properties of the constructor prototype)

return Function

Adds non-enumerable, non-configurable and non-writable properties to the prototype of constructor function.
Usage:

function MyClass() {}
_.extendProto(MyClass, {
    method1: function() {},
    method2: function() {}
});

To extend class via object:

_.extendProto(obj.constructor, methods);

Returns passed constructor, so functions .extendProto, [.extend](object.js.html#extend) and _.makeSubclass can be chained.

function extendProto(methods) {
    var propDescriptors = {};

    __.eachKey.call(methods, function(method, name) {
        propDescriptors[name] = {
            enumerable: false,
            configurable: false,
            writable: false,
            value: method
        };
    });

    Object.defineProperties(this.prototype, propDescriptors);
    return this;
}

createSubclass

function
 createSubclass() 

Option name Type Description
thisClass Function

A class to make subclass of

name String

Optional name of subclass constructor function

applyConstructor Boolean

Optional false value (not falsy) to prevent call of inherited constructor in the constructor of subclass

return Function

Makes a subclass of class thisClass.
The returned function will have specified name if supplied.
The constructor of superclass will be called in subclass constructor by default unless applyConstructor === false (not just falsy).
Copies thisClass class methods to created subclass. For them to work correctly they should use this to refer to the class rather than explicit superclass name.

function createSubclass(name, applyConstructor) {
    var thisClass = this;
    var subclass;

    // name is optional
    name = name || '';

    // apply superclass constructor
    var constructorCode = applyConstructor === false
            ? ''
            : 'thisClass.apply(this, arguments);';

    eval('subclass = function ' + name + '(){ ' + constructorCode + ' }');

    makeSubclass.call(subclass, thisClass);

    // copy class methods
    // - for them to work correctly they should not explictly use superclass name
    // and use "this" instead
    __.deepExtend.call(subclass, thisClass, true);

    return subclass;
}

makeSubclass

function
 makeSubclass() 

Option name Type Description
thisClass Function

A class that will become a subclass of Superclass

Superclass Function

A class that will become a superclass of thisClass

return Function

Sets up prototype chain to change thisClass (a constructor function) so that it becomes a subclass of Superclass.
Returns thisClass so it can be chained with .extendProto and [.extend](object.js.html#extend).

function makeSubclass(Superclass) {
    // prototype chain
    this.prototype = Object.create(Superclass.prototype);
    
    // subclass identity
    extendProto.call(this, {
        constructor: this
    });
    return this;
}

newApply

function
 newApply() 

Option name Type Description
thisClass Function

A class constructor that will be called

return Array

args Array of arguments that will be passed to constructor

Calls constructor this with arguments passed as array

function newApply(args) {
    if (! Array.isArray(args))
        args = Array.prototype.slice.call(args);
    // "null" is context to pass to class constructor, first parameter of bind
    var args = [null].concat(args);
    return new (Function.prototype.bind.apply(this, args));
}