Skip to content

Instantly share code, notes, and snippets.

@theefer
Created July 5, 2012 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theefer/3054503 to your computer and use it in GitHub Desktop.
Save theefer/3054503 to your computer and use it in GitHub Desktop.
Helper mixin to allow invoking the super method using the prototype chain
{
/**
* Invoke the super method corresponding to the caller (child-)method.
*
* Typically useful to call super constructors or destructors.
*
* @param args The arguments object of the caller method.
* @param superArguments Optional arguments to call the super method with.
* @return The result of calling the super method.
*/
invokeSuper: function(args /*, superArguments... */) {
if (!args) {
throw new Error("Missing arguments object in invokeSuper");
}
var superMethodArguments;
if (arguments.length > 1) {
superMethodArguments = Array.prototype.splice.call(arguments, 1);
} else {
superMethodArguments = args;
}
function getParentPrototype(prototype) {
// this reference is setup by Backbone
return prototype.constructor.__super__;
}
// lookup the name of the called method (bit tedious, innit?)
// FIXME: more efficient lookup? cache name?
function findMethodProperties(obj, func) {
for (var propName in obj) {
if (obj.hasOwnProperty(propName) && obj[propName] === func) {
return {object: obj, name: propName};
}
}
var parent = getParentPrototype(obj);
if (parent) {
return findMethodProperties(parent, func);
}
}
var childMethod = args.callee;
var thisPrototype = this.constructor.prototype;
var methodProperties = findMethodProperties(thisPrototype, childMethod);
if (!methodProperties) {
throw new Error("Method name not found, is the function really on the object?");
}
// call super method (if there is one)
var methodName = methodProperties.name;
var parentPrototype = getParentPrototype(methodProperties.object);
var superMethod = parentPrototype && parentPrototype[methodName];
if (superMethod) {
return superMethod.apply(this, superMethodArguments);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment