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.

Revisions

  1. jashkenas revised this gist Nov 1, 2011. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions super.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,8 @@
    // 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.");
  2. jashkenas created this gist Nov 1, 2011.
    54 changes: 54 additions & 0 deletions super.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    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.
    //