I'm not sure I understand your point here... Are you saying that the only way to solve the DCE/refactoring problem is to either always implicitly allocate or never implicitly allocate?

-Jeff

On 9/12/14, 7:22 AM, Claude Pache wrote:


Le 12 sept. 2014 à 08:39, Jeff Morrison <[email protected] <mailto:[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

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

Reply via email to