Sep 27 meeting notes
Allen Wirfs-Brock
allen at wirfs-brock.com
Thu Sep 29 18:38:42 PDT 2011
On Sep 29, 2011, at 4:54 PM, Brendan Eich wrote:
> On Sep 30, 2011, at 12:22 AM, Erik Arvidsson wrote:
> ...
>
>> class Derived extends Base { // Object literal body
>> constructor(x) { // constructor
>> this._x = x; // no special form
>> // Disallow return expr?
or if somebody wants to be ore "declarative" for their per instance state they could say:
this.{_x: x}; //or this.{x}; if they want to name the inst var x
>> } // optional comma from @awbjs
>> get x() { return this._x; }
>> prop: 42,
>> method() {} // method form @awbjs
>> };
>
> Waldemar had some objections to comma elision in object literals, they would apply here too or need to be overcome.
I don't see why:
let obj = {
x: 1, //comma required
foo () {} //comma optional
y=2} // comma optional (and the same line } is intentional
should be particularly any more objectionable than
{
x = 1; //semicolon required (if you don't practice ASI
function foo () {} //semicolon (really an empty statement) optional
y = 2} //semicolon option (most people don't think of this case as being ASI even though it is)
> If we support only methods, then class body syntax can be its own thing, and drop otiose commas or other separators. But your prop:42 needs a , after it, Waldemar's counterexample used [privateName] as the next key and that would instead "index" into the previous property's value.
>
> So why do we need prototype data properties? I'd drop them as my (4), and keep const classes (since Mark will insist, and the desugaring is easy enough -- more below).
>
>
>> This is syntactic sugar for
>>
>> var Derived = Base <| function(x) {
>> this._x = x;
>> }.prototype.{
>> get x() { ... },
>> prop: 42,
>> method() {}
>> constructor: Derived // hand wave here, needs {enumerable: false}
>> and reference to something not yet available.
>
> No need for "constructor: Derived // hand wave..." because <| clones (or unobservably mutates) its RHS function, and functions get .prototype properties with magic .constructor back-links for free. The mustache you use in the desugaring *extends* Derived.prototype, it does not lose the default .constructor back-link in that object.
>
> However, you do need a .constructor at the end, so the constructor and not its prototype is assigned to var Derived.
>
> Nit: s/var/let/ -- class should bind as let does, block-scoped and hoisted with temporal dead zone.
>
> Ok, here's the const class desugaring:
>
> const Derived =
> Object.freeze(
> Object.freeze(
> Base <| function(x) {
> this._x = x;
> Object.seal(this);
> }.prototype.{
> get x() { ... },
> prop: 42,
> method() {}
> }
> ).constructor
> );
>
> If you buy this, then I think class methods and other properties of the constructor are equally easy. We can defer them, but they do not add novel challenges as const instance variables and barriers to prevent partially initialized objects from leaking do. The only vexing issue is what syntax to use? A "static" keyword is at this point traditional, but we all hate it. Are we being too pure?
How about:
class Derived extends Base {
constructor () x {
}
...
method () {
}
}. {
/* class methods */
}
which desugars in the obvious way.
Class methods are few in number and this emphasis that you are really defining properties on the class objet
Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110929/cc17d7bf/attachment.html>
More information about the es-discuss
mailing list