Specifics of `class` and `super`
Take a look here: people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-makesuperreference-propertykey-strict . I think that should help you.
super is lexically scoped, just like this to the closest enclosing function that defines it. All function definition forms except for arrow functions introduce new this/super bindings so we can just stay that this/super binds according to the closest enclosing non-arrow function definition.
So essentially super is an alias for Object.getPrototypeOf(this)
?
I'm trying to interpret the spec but I'm somewhat new to the terms it
uses. Not exactly sure "home" is, but I'm sure it's defined elsewhere
in there so I'll keep digging into it.
Definitely not the same as Object.getPrototypeOf(this)! see people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects for definition of [[Home]] see people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-definemethod for setting the [[Home]] for a method definition see people.mozilla.org/~jorendorff/es6-draft.html#sec-super-keyword for evaluating the super keyword
OnMon, Dec 9, 2013 at 10:22 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
super is lexically scoped
This is true.
James Long wrote:
So essentially super is an alias for
Object.getPrototypeOf(this)
?
But this
is not lexically scoped, so your question's answer must be "no".
I read Allen's email wrong, thought it implied this
was lexically
scoped (which I know is not true. very little sleep at an airport...).
I'll keep digging through the spec, but if someone has a quick example
what ES5 code I could compile to for roughly the same semantics, that
would be helpful. From what I understand, you're saying that super
is lexically scoped to the class
that is defined so I can statically
compile it out to something like Foo.prototype.method
if Foo
is
the parent class. Anyway, no need to trail on about this, I should
just RTFS.
You could also check the output of Traceur and TypeScript. I don't know how close either of them are to implementing the exact semantics of ES6 classes, but I'm sure it'll be helpful in any case.
super.foo(x)
is equivalent to
Object.getPrototypeOf(me.[[HomeObject]]).foo.call(this, x);
(where me
refers to the current function)
On Mon, Dec 9, 2013 at 2:36 PM, Till Schneidereit <till at tillschneidereit.net> wrote:
You could also check the output of Traceur and TypeScript. I don't know how close either of them are to implementing the exact semantics of ES6 classes, but I'm sure it'll be helpful in any case.
On Dec 9, 2013, at 9:28 AM, James Long wrote:
I read Allen's email wrong, thought it implied
this
was lexically scoped (which I know is not true. very little sleep at an airport...).I'll keep digging through the spec, but if someone has a quick example what ES5 code I could compile to for roughly the same semantics, that would be helpful. From what I understand, you're saying that
super
is lexically scoped to theclass
that is defined so I can statically compile it out to something likeFoo.prototype.method
ifFoo
is the parent class. Anyway, no need to trail on about this, I should just RTFS
For an instance method defined in a class definition, [[Home]] is the instance prototype object defined by the class. For a static method defined in a class definition [[Home]] is the class object (ie, the constructor function) itself.
super is not equivalent to a static reference to the super class or super class prototype be super must remain sensitive to prototype chain changes performed using Object.setPrototypeOf()
One way you can approximate [[Home]] in ES5 is to create a __Home property on the function objects that represent methods. Because [[Home]] never changes the __Home property could be non-writable, non-configurable.
At the last TC39 meeting there some decisions made about the use of super outside of class definitions. Those decisions are not yet reflected in the ES6 draft.
TS is known to get this wrong in the name of simplicity.
Traceur gets it right inside class bodies. We do not support toMethod (not even sure if this is doable).
google/traceur-compiler/blob/master/test/feature/Classes/SuperChangeProto.js, goo.gl/0kV4ts
If you have an inner function that calls super
, Traceur keeps track
of the outer "this" and makes sure to call it with that. TypeScript
does not do this. Is this correct?
class Bar extends Foo {
nestedFunction() {
function run() {
return super.getX();
}
return run();
}
}
This code compiles to:
nestedFunction: function() {
var $__0 = this;
function run() {
return $__superCall($__0, $__proto, "getX", []);
}
return run();
}
where $__superCall
basically just does $__proto["getX"].apply($__0, [])
. But note that it saved the outer this
in $__0
and called it with that.
super is lexically bound.
On Mon, Dec 9, 2013 at 7:39 PM, James Long <longster at gmail.com> wrote:
If you have an inner function that calls
super
, Traceur keeps track of the outer "this" and makes sure to call it with that. TypeScript does not do this. Is this correct?
TypeScript, also does not correctly support super getters/setters:
class B {
get x() {
return 1;
}
}
class C extends B {
get x() {
return 1 + super.x;
}
}
James, it looks like you are using an older version of Traceur which has some bugs related to the [[HomeObject]] starting at the wrong object.
First posting to this mailing list. I'm defining a few ES6 features as sweet.js macros so existing projects can easily leverage them. I also happen to think macros are a big deal for JS and this is how future extensions should be defined... (at least ones that are mostly syntactic) My project is here: jlongster/es6-macros
I'm working on
class
, and it's mostly working. You can see the tests here: jlongster/es6-macros/blob/master/tests/class.sjs, and the generated code here: jlongster/es6-macros/blob/master/tests/class.jsMy question is with
super
. I've searched the archives and read the spec to answer most of my questions, but one thing is unclear. What exactly is the scope ofsuper
? Is it valid to usesuper
inside a nested function, like in this example? jlongster/es6-macros/blob/master/tests/class.sjs#L91If so,
super
seems somewhat magical in that it can resolve the prototype of athis
object that isn't available (when that function is called,this
is not the object anymore). Are there clear rules with howsuper
is resolved somewhere?