<div dir="ltr"><br><br><div class="gmail_quote">On Thu, Mar 5, 2015 at 1:40 PM Luke Scott <<a href="mailto:luke@cywh.com">luke@cywh.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Mar 5, 2015, at 9:20 AM, Kevin Smith <<a href="mailto:zenparsing@gmail.com" target="_blank">zenparsing@gmail.com</a>> wrote:</div><br><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>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.<br></div></div></blockquote><div><br></div><div>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:</div><div><br></div><div>    class C {}</div><div>    if (someCondition) {</div><div>     C = class OtherC {};</div><div>    }</div><div><br></div><div>But you can always write the above as:</div><div><br></div><div>    let C = class {};</div><div>    if (someCondition) {</div><div>     C = class OtherC {};</div><div>    }</div><div><br></div><div>I think you've sold me.  I'm worried that there might be other hacker-use-cases that I'm not considering, though.</div></div></div></div></div></blockquote></div><div><br></div></div><div style="word-wrap:break-word"><div>Isn’t making `Foo` a const inconsistent with the rest of the language? You can redefine a function. Currently you can do this anyway:</div><div><br></div><div><div>const C = class {};</div></div></div><div style="word-wrap:break-word"><div><div>if (someCondition) {</div><div> C = class OtherC {};</div><div>}</div></div></div><div style="word-wrap:break-word"><div></div><div><br></div><div>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:</div><div><br></div><div>```</div><div>class Foo {</div><div>  static makeFoo() {</div><div>    return new Foo(); // Foo should be undefined!</div><div>  }</div><div>}</div><div>// Foo should be considered defined at this point.</div><div>``</div></div></blockquote><div><br></div><div>By the time Foo.makeFoo() becomes callable, Foo will be defined, so this doesn't make sense. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Because you can do this and it would likely not be correct either:</div><div><br></div><div>```</div><div>class Foo {</div><div>  static makeFoo() {</div><div>    return new Foo();</div><div>  }</div><div>  foo() {</div><div><br></div><div>  }</div><div>}</div><div><br></div><div>var FooWithLogging = class extends Foo {</div><div>  foo() {</div><div>    super.foo();</div><div>    console.log(“log!”);</div><div>  }</div><div>}</div><div><br></div><div>FooWithLogging.makeFoo().foo();</div><div>```</div><div><br></div><div>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.</div><div><br></div><div>Although getting at `constructor` is a bit cumbersome, so it would be nice if a `self` keyword existed:</div></div></blockquote><div><br></div><div>Maybe? </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div><div>```</div><div>class Foo {</div><div>  method() {</div><div>    new self(); // same as `new this.constructor()`</div><div>  }</div><div>  static method() {</div><div>    new self(); // same as `new this.prototype.constructor()`</div><div>  }</div><div>}</div></div></div></blockquote><div><br></div><div>That isn't impossible, but...</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><br></div><div>function foo() {</div><div>    self(); // same thing as `foo()`</div><div>}</div><div>```</div></div></div></blockquote><div><br></div><div>This would be a breaking change: `self` is not a reserved or future reserved word (in any mode). </div><div><br></div><div>Rick</div></div></div>