Skip to content
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
Closed

ES6 classes need fixing #35

nmn opened this issue Apr 7, 2016 · 6 comments

Comments

@nmn
Copy link

@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
Copy link
Member

@ljharb 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
Copy link
Author

@nmn 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
Copy link
Member

@ljharb 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
Copy link
Author

@nmn 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
Copy link
Member

@jeffmo 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
Copy link

@bathos 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
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.