proteus
Version:
A declarative way of creating objects, properties, and classes in ES5 JavaScript
71 lines (63 loc) • 1.78 kB
JavaScript
var putil = require("proteus/util"),
slice = putil.slice,
hasOwnProp = Object.prototype.hasOwnProperty,
callProto
;
/**
* Apply a method from the objects prototype.
*
* @method applyProto
* @param self {object} the scope object
* @param name {string} name of the method to call, optional if the calling
* function is named i.e:
* {
* init: function init () {...}
* }
* @param args {array-like} arguments to pass to the method
* @returns {mixed} whatever the prototype method would return
*/
function applyProto (self, name, args) {
var hasOwn = hasOwnProp,
caller = applyProto.caller === callProto ?
callProto.caller :
applyProto.caller,
callerFound, p
;
if (typeof name !== "string") {
args = name;
name = caller.name;
}
if (!name) {
throw new Error("Can not call prototype method without a name");
}
p = self;
do {
if (p[name] === caller) {
callerFound = true;
p = Object.getPrototypeOf(p);
}
if (p && callerFound && hasOwn.call(p, name)) {
return p[name].apply(self, args);
}
}
while ((p = Object.getPrototypeOf(p)));
throw new Error("Can not call '" + name + "' on undefined.");
}
/**
* Call a method from an objects prototype.
*
* @method callProto
* @param self {object} the scope object
* @param name {string} name of the method to call
* @returns {mixed}
*/
callProto = function callProto (self, name) {
return applyProto(
self,
name,
slice(arguments, 2));
};
module.exports = {
applyProto: applyProto,
callProto: callProto
};