super() call in methods
On Dec 16, 2014, at 1:18 PM, Bergi wrote:
...
I've read esdiscuss.org/topic/referencing-super and it seems that needing to call
super.describe()/super.render()/super.say()is intended behaviour. I'm fine with that, as explicit is better than implicit and "finding the method with the same name" (or something like that) is overly complicated and maybe even ambiguous.
Yes, this is a fairly recent change to the ES6 draft specification. People who write public commentary and tutorials about ES6 need to keep up with evolving spec. changes.
However, it seems that we need to communicate better that
super()calls only work in constructors, and other functions that inherit from functions (people.mozilla.org/~jorendorff/es6-draft.html#sec-getsuperconstructor). That seems to be the reason why the method name GetSuperConstructor() was chosen in the spec.
Rev 29 made new super and new super ( ) early errors in non-constructor concise methods. It doesn't do the same thing for super( ) calls that appears to be an editorial mistake that I will correct in Rev 30.
Yet,
super()calls in plain methods would actually work! The method objects would inherit fromFunction.prototype, which is itself callable: a no-op function. This might lead to subtle bugs, wheresuper()was intended to call the parent class's method, but does nothing - not even throwing an error!
Should an exception been thrown if the
funcreturned byGetSuperConstructor()is%FunctionPrototype%?
It it [[Prototype]] was set ot %FunctionPrototype% from a different realm?
I think the early error described above is a better solution as it address the syntactic context of the usage rather than actual runtime value.
Allen Wirfs-Brock schrieb:
Yes, this is a fairly recent change to the ES6 draft specification. People who write public commentary and tutorials about ES6 need to keep up with evolving spec changes.
Sure they do, but I didn't even know that there was an earlier revision where this had once worked. Thanks for the clarification!
Rev 29 made
new superandnew super ( )early errors in non-constructor concise methods.
Ah, people.mozilla.org/~jorendorff/es6-draft.html#sec-object-initializer-static-semantics-early-errors and people.mozilla.org/~jorendorff/es6-draft.html#sec-class-definitions-static-semantics-early-errors.
I had not seen that.
It might be nice if there was a note about these in the Static Semantics
for the super keyword productions
(people.mozilla.org/~jorendorff/es6-draft.html#sec-super-keyword-static-semantics-early-errors)
It doesn't do the same thing for
super( )calls that appears to be an editorial mistake that I will correct in Rev 30.
Thanks!
I think the early error described above is a better solution as it address the syntactic context of the usage rather than actual runtime value.
Yes indeed. This will fit the needs of the majority who declare their
methods in object literals or classes much better than a runtime
exception (which was just the first idea that had come to my mind). And
we probably don't need to care about those who manually assign functions
and call .toMethod() etc.
However, I wonder whether the same thing should be done in non-concise
method assignments, i.e. PropertyDefinition : PropertyName : AssignmentExpression. As the PropertyDefinitionEvaluation handles the
"IsFunctionDefinition of AssignmentExpression" case specially, I think
the static semantics for it should do so as well (and forbid super
calls in them).
On Dec 16, 2014, at 4:18 PM, Bergi wrote:
However, I wonder whether the same thing should be done in non-concise method assignments, i.e.
PropertyDefinition : PropertyName : AssignmentExpression. As thePropertyDefinitionEvaluationhandles the "IsFunctionDefinition of AssignmentExpression" case specially, I think the static semantics for it should do so as well (and forbidsupercalls in them).
But there is a difference here. Functions defined in this manner are constructors (the support [[Construct]] while concise methods are not.
I've just read the spec draft on the super keyword to answer a StackOverflow question.
From what I understood, it's currently not possible call a super method using only
super(), contrary to common (my?) intution. A quick web search shows that other people think similar:www.2ality.com/2011/11/super-references.html (with a 2013 update):
javascriptplayground.com/blog/2014/07/introduction-to-es6-classes-tutorial/:
esdiscuss.org/topic/base-value-of-super-reference-indicates-the-prototype-object-of-the-current-derived-class:
I've read esdiscuss.org/topic/referencing-super and it seems that needing to call
super.describe()/super.render()/super.say()is intended behaviour. I'm fine with that, as explicit is better than implicit and "finding the method with the same name" (or something like that) is overly complicated and maybe even ambiguous.However, it seems that we need to communicate better that
super()calls only work in constructors, and other functions that inherit from functions (people.mozilla.org/~jorendorff/es6-draft.html#sec-getsuperconstructor).That seems to be the reason why the method name GetSuperConstructor() was chosen in the spec. Yet,
super()calls in plain methods would actually work! The method objects would inherit fromFunction.prototype, which is itself callable: a no-op function. This might lead to subtle bugs, wheresuper()was intended to call the parent class's method, but does nothing - not even throwing an error!Should an exception been thrown if the
funcreturned byGetSuperConstructor()is%FunctionPrototype%?PS: there's a typo in
GetSuperConstructor: s/activeFuntion/activeFunction/Hi! I've just read the spec draft <http://people.mozilla.org/~jorendorff/es6-draft.html> on the super keyword to answer a StackOverflow question <http://stackoverflow.com/a/27511897/1048572>. From what I understood, it's currently not possible call a super method using only `super()`, contrary to common (my?) intution. A quick web search shows that other people think similar: http://www.2ality.com/2011/11/super-references.html (with a 2013 update): | Super-references (including super-calls) are a feature of ECMAScript | 6 which allows one to write describe() much more succinctly: | | Employee.prototype.describe = function () { | // super() is an abbreviation of super.describe() | return super()+" ("+this.title+")"; | }; | | Although they look similar, super and this are independent features. | super means “I’m currently in a method – find the method that that | method has overridden and apply it to the same instance that is | presently active (i.e., this stays the same)” http://javascriptplayground.com/blog/2014/07/introduction-to-es6-classes-tutorial/: | class LogView extends View { | render() { | var compiled = super(); | console.log(compiled); | } | } | | We first call super(). This calls the parent class' render() method, | and returns the result. This means that the render method on the View | class is first called, and the result is stored in the compiled | variable. https://esdiscuss.org/topic/base-value-of-super-reference-indicates-the-prototype-object-of-the-current-derived-class: | class Base { | say() { | console.log('base'); | } | }; | | class Derived extends Base { | say() { | console.log('derived'); | super(); | } | }; | | let instance = new Derived; | instance.say(); I've read <https://esdiscuss.org/topic/referencing-super> and it seems that needing to call `super.describe()`/`super.render()`/`super.say()` is intended behaviour. I'm fine with that, as explicit is better than implicit and "finding the method with the same *name*" (or something like that) is overly complicated and maybe even ambiguous. However, it seems that we need to communicate better that `super()` calls only work in constructors, and other functions that inherit from functions (<http://people.mozilla.org/~jorendorff/es6-draft.html#sec-getsuperconstructor>). That seems to be the reason why the method name GetSuper*Constructor*() was chosen in the spec. Yet, `super()` calls in plain methods would actually work! The method objects would inherit from `Function.prototype`, which is itself callable: a no-op function. This might lead to subtle bugs, where `super()` was intended to call the parent class's method, but does nothing - not even throwing an error! Should an exception been thrown if the `func` returned by `GetSuperConstructor()` is `%FunctionPrototype%`? Best regards, Bergi PS: there's a typo in `GetSuperConstructor`: s/activeFuntion/activeFunction/