Skip to content

Instantly share code, notes, and snippets.

@jashkenas
Created November 1, 2011 17:45
Show Gist options
  • Select an option

  • Save jashkenas/1331310 to your computer and use it in GitHub Desktop.

Select an option

Save jashkenas/1331310 to your computer and use it in GitHub Desktop.
// Demonstration of dynamic super() calls.
// Because of JS reserved words, "ssuper()" is the method name,
// and is passed the current object, as well as the name of
// the current method.
function GreatGrandParent() {};
GreatGrandParent.prototype.method = function() {
console.log("In the GreatGrandParent.");
};
function GrandParent() {};
GrandParent.prototype = new GreatGrandParent;
GrandParent.prototype.method = function() {
ssuper(this, 'method');
console.log("In the GrandParent.");
};
function Parent() {};
Parent.prototype = new GrandParent;
Parent.prototype.method = function() {
ssuper(this, 'method');
console.log("In the Parent.");
};
function Child() {};
Child.prototype = new Parent;
Child.prototype.method = function() {
ssuper(this, 'method');
console.log("In the Child.");
};
function ssuper(object, method) {
// Initialize an object-specific super depth counter. If desired, the counter
// can be specific to per-object-per-method-name.
var depth = object._superCount || (object._superCount = 1);
var proto = object.__proto__;
// Walk the prototype chain to the correct level of "super" ness.
while(depth--) proto = proto.__proto__;
// Increment the super counter.
object._superCount++;
// Actually call super().
proto[method].call(object);
// Decrement the super counter.
object._superCount--;
// We're done with this particular recursive super() call. Remove the record.
if (object._superCount <= 1) delete object._superCount;
};
(new Child).method();
// Pasting the above block of code into a browser console yields:
//
// In the GreatGrandParent.
// In the GrandParent.
// In the Parent.
// In the Child.
//
@rauschma
Copy link

rauschma commented Nov 3, 2011

@jashkenas: Example.

function A() {
}
A.prototype.desc = function() {
    console.log("A");
}

function B() {
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
B.prototype.desc = function() {
    console.log("B");
    ssuper(this, "desc");
}

function C() {
}
C.prototype = Object.create(B.prototype);
C.prototype.constructor = C;

new C().desc()

Output:

B
B
A

When B.prototype.desc() makes the super-call, it initially calls itself.

I contend that you need to somehow record in _superCount where you actually found a given property. For example: gist.github.com/1331748

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