Skip to content

Instantly share code, notes, and snippets.

@seaneagan
Created June 20, 2011 18:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seaneagan/1036200 to your computer and use it in GitHub Desktop.
Save seaneagan/1036200 to your computer and use it in GitHub Desktop.
Orthogonalized super keyword

Orthogonalized super keyword

There are two active proposals for what to do with the reserved word "super", object initialiser super and classes. Both proposals limit the context in which "super" can appear. This proposal attempts to allow "super" anywhere by basing it's behavior on ThisBindings.

Details

Execution contexts are updated to have a SuperBinding similar to the existing ThisBinding. The keyword "super" by itself evaluates to the value of the SuperBinding of the current execution context. Direct function calls, e.g. f() or f.call(this, arg), result in a SuperBinding of the [[Prototype]] internal property of the passed ThisBinding or undefined it the ThisBinding is not an object. Method calls, e.g. o.m(), and accessor property access, e.g. o.p where "p" is an accessor property somewhere in o's property lookup chain (own properties plus prototype chain), result in a SuperBinding which is the [[Prototype]] internal property of the object in o's property lookup chain on which the method or accessor property was found. Method calls and accessor property access on "super", e.g. super.method(), super.accessor, or super.accessor = "foo", is treated differently in that the ThisBinding used is the same as the ThisBinding of the execution context in which the property access occurs, rather than the base value of the property access, i.e. the SuperBinding.

When a proxy is in the property lookup chain, since proxies fully handle prototype climbing, if the proxy's handler defines a "get" trap, it might need to additionally return the object in its property lookup chain on which it found the property so that if the property is a function (method) it can be called with the correct SuperBinding. The "getPropertyDescriptor" trap return could be similarly extended to support accessor property SuperBindings within the default "get" and "set" behavior, except that this would make the default "get" and "set" behavior not definable in terms of ES since there is currently no mechanism to explicitly set the SuperBinding when calling a function, however, such a mechanism could potentially be added. This brings up the question though, is it necessary to have proto-climbing traps in the first place since this allows proxies to ignore their [[Prototype]] internal property, and also many (most?) use cases could presumably be handled by having the [[Prototype]] internal property of the proxy also be a proxy, especially if an "observe" API were additionally available.

Examples

This definition of "super" works nicely with the prototypes as the new class declaration idea, where constructors are just methods of prototype objects.

// As proposed in the "prototypes as the new class declaration" thread
Object.prototype.new = function() {
  return Object.create(this);
}

let A = {
  new: function(x) {

    let o = this <| {x};
    o.m();
    return o;

  },
  m: function() {return this;},
  get p() {return this;},
  set p(v) {return this;}
};

let B = A <| {
  new: function(x, y) {

    let o = super.new(x);
    o.y = y;
    o.m();
    return o;

  }
}

let m = function() {

    // call "super" methods and accessor getters and setters
    let methodReturn = super.m();
    let getReturn = super.p;
    let setReturn = super.p = "foo";

    // verify correct ThisBindings used
    assert(methodReturn === this);
    assert(getReturn === this);
    assert(setReturn === this);

    // verify super binding
    assert(super === A);

};

// B.m is non-configurable, non-writable, and non-enumerable
Object.defineProperty(B, "m", {value: m});

let b = B.new("x", "y");

TODO

  • Add support for "get super set" and "set super get" from the object initialiser super proposal.
  • Define the SuperBinding of global and eval code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment