Le 12 sept. 2014 à 08:39, Jeff Morrison <[email protected]> a écrit :

> " If a constructor body contains an assignment of the form this = then 
> automatic allocation is not performed and the constructor is expected to 
> perform manual allocation."
> If I'm understanding this correctly, this means that snippet (A) would never 
> have access to `this`, but snippet (B) would have an implicit `this` binding 
> -- is that correct?
> 
> (A)
> ```
> class Foo extends Bar {
>   constructor() {
>     if (false) {
>       this = super();
>     }
>     this; // undefined
>   }
> }
> ```
> 
> (B)
> ```
> class Foo extends Bar {
>   constructor() {
>     // No call to `this =` present in the constructor 
>     this; // the automatically allocated object -- i.e. this !== undefined
>   }
> }
> ```
> 
> If this is the case, it occurs to me that it would raise issues for things 
> like automated refactoring and/or dead code elimination (as a minifier might 
> do).
> Normally a minifier (or even a human) would expect to be able to eliminate 
> the entire conditional altogether if they were confident the condition never 
> evaluated to true. But with this static pre-check acting as the indicator for 
> whether automatic allocation/binding should happen, doing so would cause the 
> constructor to act very unexpectedly differently in the two cases.
> 
> I wish I could suggest an alternative, but nothing comes to mind right now.
> 
> Thoughts?

So, let's explore how to cope with the design that consists to determine the 
automaticity of allocation/binding independently of the actual code of the 
constructor (as it was the case in my original design.) 

The rule must be the following one:

* For constructors in classes, automatic allocation occurs if and only if there 
is no `extends` clause.
* For constructors defined the ES1-5 way (outside classes), automatic 
allocation occurs.

That is satisfying for most cases while remaining backward compatible with 
ES1-5, but it is a priori problematic in the following situations, where one 
may want manual allocation whereas the rule mandates an automatic one.

(1) Base classes (i.e., classes without `extends` clause) that want manual 
allocation. The legacy possibility of returning an alien object from the 
constructor remains. Alternatively, the following hack is possible, provided 
that we accept `Function.prototype` as a constructor.

        class Base extends Function.prototype { /* ... */  } 

(IIUC, the prototype chain for both constructor and instances will be the same 
as without the `extends Function.prototype` clause.) If that situation occurs 
often, we might want to provide sugar around that.

(2) Constructors defined outside classes that want manual allocation of `this`. 
For these, I propose the following syntax:

        function Derived(a, b) extends Base { /* ... */ }

as an almost equivalent of:

        function Derived(a, b) { /* ... */ }
        Derived.__proto__ = Base
        Derived.prototype = { __proto__: Base.prototype || Object.prototype, 
constructor: Derived }

except that the automatic allocation of `this` does not occurs in the former 
case. Like constructors defined in classes, the `extends Function.prototype` 
trick is possible.

—Claude
        

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to