Class double-bind

Rick Waldron waldron.rick at gmail.com
Thu Mar 5 19:01:50 UTC 2015


On Thu, Mar 5, 2015 at 1:40 PM Luke Scott <luke at cywh.com> wrote:

>
> On Mar 5, 2015, at 9:20 AM, Kevin Smith <zenparsing at gmail.com> wrote:
>
> However, the double-binding issue makes this weirder. If non-const-class
>> declarations were like non-const-function declarations, where there is only
>> one binding per defining occurrence, then I would fully agree. But this
>> issue of one defining occurrence creating two bindings that can diverge is
>> a new level of unpleasantness. I agree this calls for the issue to be fixed
>> now in ES6 if we can, for non-const-classes.
>>
>
> OK - I see.  So on one side (double-binding) the risk is that someone will
> change the outer binding and violate an implicit assumption that references
> inside the class body and outside point to the same thing.  On the other
> side, the risk is that we disable hackery like:
>
>     class C {}
>     if (someCondition) {
>      C = class OtherC {};
>     }
>
> But you can always write the above as:
>
>     let C = class {};
>     if (someCondition) {
>      C = class OtherC {};
>     }
>
> I think you've sold me.  I'm worried that there might be other
> hacker-use-cases that I'm not considering, though.
>
>
> Isn’t making `Foo` a const inconsistent with the rest of the language? You
> can redefine a function. Currently you can do this anyway:
>
> const C = class {};
> if (someCondition) {
>  C = class OtherC {};
> }
>
> If not fixing the double bind not an option? If it isn’t an option, why
> not make a class reference itself by name be an undefined error:
>
> ```
> class Foo {
>   static makeFoo() {
>     return new Foo(); // Foo should be undefined!
>   }
> }
> // Foo should be considered defined at this point.
> ``
>

By the time Foo.makeFoo() becomes callable, Foo will be defined, so this
doesn't make sense.


>
> Because you can do this and it would likely not be correct either:
>
> ```
> class Foo {
>   static makeFoo() {
>     return new Foo();
>   }
>   foo() {
>
>   }
> }
>
> var FooWithLogging = class extends Foo {
>   foo() {
>     super.foo();
>     console.log(“log!”);
>   }
> }
>
> FooWithLogging.makeFoo().foo();
> ```
>
> In most (all?) of these situations `this.constructor` or
> `this.prototype.constructor` should be used anyway, right? Doing that in
> Jason’s example bypasses the binding issue.
>
> Although getting at `constructor` is a bit cumbersome, so it would be nice
> if a `self` keyword existed:
>

Maybe?


>
> ```
> class Foo {
>   method() {
>     new self(); // same as `new this.constructor()`
>   }
>   static method() {
>     new self(); // same as `new this.prototype.constructor()`
>   }
> }
>

That isn't impossible, but...


>
> function foo() {
>     self(); // same thing as `foo()`
> }
> ```
>

This would be a breaking change: `self` is not a reserved or future
reserved word (in any mode).

Rick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150305/e8687326/attachment-0001.html>


More information about the es-discuss mailing list