New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6 classes need fixing #35

Closed
nmn opened this Issue Apr 7, 2016 · 6 comments

Comments

Projects
None yet
4 participants
@nmn

nmn commented Apr 7, 2016

We're adding all this extra syntax just for ES6 classes. Case in point instance and static fields but also decorators.

Decorators won't work with normal functions. But really decorators are nothing more than higher order functions. We shouldn't need new syntax for this stuff.

Instead, using the class fields, we could make the class syntax a little more sane. (It's too late for a re-write)

Problems with ES6 classes

  1. Functions/methods are given special status:
    Javascript has always had first-class functions. In the ES5 days writing classes in JS was clunky, but ES6 classes, methods have become something different than simple values.
    Currently, all methods in a class body get attached to the prototype. But there is no way to attach NON-function values to the prototype anymore.
  2. You can no longer use the word function.

You can't write this:

class X {
  someMethod: function() {... }
}
// OR
class X {
  someMethod = function() {... }
}

With the fields proposal, the second would work but would get attached to each instance, instead of the prototype.

Conclusion

Let me just end here and say ES6 classes have problems, and before we try hacking around it's flaws we should consider making it better.

So perhaps:

class X {
  someMethod = function() {... }
}

should be equivalent to

class X {
  someMethod() {... }
}

And decorators can be applied like so:

class X {
  someMethod = decorate(function() {... })
}

Instead of trying to look more and more like other languages (cough Java cough). Maybe we should try to keep Javascript more internally consistent.

PS:

I also really dislike the requirement of semi-colons at the end of field declarations. Does it really need to be there? I know about the computed names for methods being an edge-case, but surely there's another way around that. Maybe the semi-colons can be optional, just like the rest of Javascript.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Apr 7, 2016

Member
  1. decorators will likely work with normal functions, it's still an open question as I understand it. Certainly something that only works for "class" syntax will have a tough time making it all the way through the process.
  2. decorators aren't part of this proposal, so unless there's a cross-cutting concern (something in either proposal that conflicts with each other), they're not particularly relevant.
  3. "not using the word function" is generally considered an improvement, since it removes boilerplate.
  4. object literals have concise methods as well, so ES6 classes are not special in this regard, and the most common consensus around style guides for this is to always use concise methods in every context.
  5. there is no requirement for semicolons. the same ASI rules that apply throughout JS will apply here - a semicolon is only required when the statement on the next line is ambiguous such that the semicolon won't be automatically inserted.
Member

ljharb commented Apr 7, 2016

  1. decorators will likely work with normal functions, it's still an open question as I understand it. Certainly something that only works for "class" syntax will have a tough time making it all the way through the process.
  2. decorators aren't part of this proposal, so unless there's a cross-cutting concern (something in either proposal that conflicts with each other), they're not particularly relevant.
  3. "not using the word function" is generally considered an improvement, since it removes boilerplate.
  4. object literals have concise methods as well, so ES6 classes are not special in this regard, and the most common consensus around style guides for this is to always use concise methods in every context.
  5. there is no requirement for semicolons. the same ASI rules that apply throughout JS will apply here - a semicolon is only required when the statement on the next line is ambiguous such that the semicolon won't be automatically inserted.
@nmn

This comment has been minimized.

Show comment
Hide comment
@nmn

nmn Apr 7, 2016

@ljharb

Note: not trying to argumentative here, but I need to clarify my point.

1 & 2. decorators are currently blocked for functions as functions 'hoist'. But in any case I understand that it's a completely separate proposal, and I only brought it up to point out the problems with ES6 class syntax.

3 & 4. Not using the word function is an improvement. But I dislike the fact that you can no longer use the word function. That is actually a bad example. The bigger problem is that you can no longer use references to functions defined externally:

function worksAsAMethod () {...}

class X {
  myMethod: worksAsAMethod // doesn't work
  myMethod= worksAsAMethod // will work with this proposal, but won't get put on the prototype.
}
  1. I may be incorrect in this. But I saw an issue explaining how this proposal makes semi-colons mandatory after field definitions. If they are only needed when the next field/method starts with a [ then ignore my statement about semi-colons here.

nmn commented Apr 7, 2016

@ljharb

Note: not trying to argumentative here, but I need to clarify my point.

1 & 2. decorators are currently blocked for functions as functions 'hoist'. But in any case I understand that it's a completely separate proposal, and I only brought it up to point out the problems with ES6 class syntax.

3 & 4. Not using the word function is an improvement. But I dislike the fact that you can no longer use the word function. That is actually a bad example. The bigger problem is that you can no longer use references to functions defined externally:

function worksAsAMethod () {...}

class X {
  myMethod: worksAsAMethod // doesn't work
  myMethod= worksAsAMethod // will work with this proposal, but won't get put on the prototype.
}
  1. I may be incorrect in this. But I saw an issue explaining how this proposal makes semi-colons mandatory after field definitions. If they are only needed when the next field/method starts with a [ then ignore my statement about semi-colons here.
@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Apr 7, 2016

Member

What's the use case for defining a function outside of a "class" body and then installing it on a prototype, versus defining a new function that dispatches to the function in question?

Member

ljharb commented Apr 7, 2016

What's the use case for defining a function outside of a "class" body and then installing it on a prototype, versus defining a new function that dispatches to the function in question?

@nmn

This comment has been minimized.

Show comment
Hide comment
@nmn

nmn Apr 7, 2016

@ljharb You offer a good workaround. But I ask we should even need such a workaround. I'm not trying to say ES6 classes don't work. They just don't work well. Bring weird limitations that don't 'fit' in with javascript's dynamic nature.

nmn commented Apr 7, 2016

@ljharb You offer a good workaround. But I ask we should even need such a workaround. I'm not trying to say ES6 classes don't work. They just don't work well. Bring weird limitations that don't 'fit' in with javascript's dynamic nature.

@jeffmo

This comment has been minimized.

Show comment
Hide comment
@jeffmo

jeffmo Aug 16, 2016

Member

Cleaning up issues. Feedback certainly welcome, but I'm not too sure what's actionable here so going to close this out since it's been a while.

Member

jeffmo commented Aug 16, 2016

Cleaning up issues. Feedback certainly welcome, but I'm not too sure what's actionable here so going to close this out since it's been a while.

@jeffmo jeffmo closed this Aug 16, 2016

@bathos

This comment has been minimized.

Show comment
Hide comment
@bathos

bathos Dec 5, 2016

Wow @nmn ... I know it’s far too late, but I wish you had been on the tc39 board two years ago :)

bathos commented Dec 5, 2016

Wow @nmn ... I know it’s far too late, but I wish you had been on the tc39 board two years ago :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment