tc39 / proposal-class-fields

Orthogonally-informed combination of public and private fields proposals
https://arai-a.github.io/ecma262-compare/?pr=1668
1.72k stars 113 forks source link

Let's vote, language is make for us, but not for aliens! #285

Closed MegaJSDeveloper closed 4 years ago

MegaJSDeveloper commented 4 years ago

Current code:

class Cat {
  #lol = 11
  say(){ return this.#lol }  
}

Simplified access:

class Cat {
  #lol = 11
  say(){ return #lol }  
}

There are no variables starting with the symbol #, therefore, unlike public properties, there will be no syntactic confusion.

We do not write:

class Cat {
  this.#lol = 11
  say(){ return this.#lol }  
}

we write without this, so we should be able to access such properties without this. Yes, I know all your arguments, but I think let the community decide, all the same, we use this language, not you.

Private methods

Actually private methods can accessed without this prop, therefore private fields should:

class Cat{
  #privateMethod() {
    return 'hello world';
  }

  publicMethod() {
      return #privateMethod()
  }
}

Proof https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes/Class_fields

And let the community decide, not Committee.

shannon commented 4 years ago

I'm not arguing one way or the other here but that's got to be a typo in MDN for private instance methods right?

Having said that, I believe what TC39 will say here is that use case for accessing the property on another object is important. And this approach does not provide a way to achieve this.

For example, would this be valid?

class Example {
  #foo = 1;
  method(objB) {
    return objB.#foo + #foo;
  }
}

Again, not really arguing for or against this approach, I've just seen this conversation many times. I believe it was originally planned to provide the ability to access private fields without this but it was removed or the plan was dropped for one reason or another.

MegaJSDeveloper commented 4 years ago

@shannon there is no reason, no minuses were found, we just in case decided to wait, and let the community test everything in babel, as far as I remember., we just left it as a potential improvement, it is time to apply it =)

Even my IDE already support this syntax:

image

image

image

what is the problem?

nicolo-ribaudo commented 4 years ago

I have good news for you!

This syntax was already present in an older version of the proposal, but was removed because many TC39 members prefer a "maximally minimal" approach: first, give the lowest amount of syntax to make a feature usable while still giving tangible benefits; then, learn how the feature is actually used by developers and propose new improvements. This is similar to the history of classes in ECMAScript: first, they proposed classes with only public methods and accessors. This was already a big improvement over the previous non-existing syntax, where you had to manually manipulate prototype chains. Now, after a few years, they are working on this new feature to expand their functionality.

In the FAQ document, you can find two different entries which explain that some of the design decisions of this proposal have been made to make it possible to propose shorthand syntax in the feature:

  1. Why not have access be this#x, without the dot?
  2. Why was the sigil # chosen, among all the Unicode code points? (third bullet point)

That said, I (and currently no one else) can't guarantee that it will be accepted in the standard or even proposed, but there are people who are definitely interested in it :wink:

MegaJSDeveloper commented 4 years ago

@nicolo-ribaudo let's vote anyway)

aral commented 4 years ago

Any word on where things are with this (no pun intended?)

As there’s no ambiguity, not having to use this to dereference private fields makes the code more legible.

ljharb commented 4 years ago

@aral there's tons of ambiguity, both because private fields need to be accessed on other objects (imagine static compare(a, b) { return a.#id === b.#id; }, and because making this magic in yet another way would add to user confusion around the concept. Having the receiver explicitly present imo does make the code more legible, since explicit > implicit.

The shorthand could be a separate proposal that nobody's made yet, but I don't think I'm the only one philosophically opposed to it existing, so I suspect it wouldn't progress.

aral commented 4 years ago

@ljharb Mock documentation:


A hashname (‘#foo’) denotes a private field. From within an instance, you can refer to private fields using ‘this.#foo’ or, as a shorthand, as just ‘#foo’. One instance can also access a private field on another instance of the same class (eg. ‘otherInstance.#foo’).


Having a shorthand for the most common usage is not without precedent (see Swift, etc.) and I don’t feel it is mutually exclusive with the common-sense requirement that you must include the reference if you’re addressing a different instance.

The convention can also carry to static fields (and remove the need to type out ‘ClassName.#foo’) and might actually make for a good separate proposal as, if implemented, it should apply to private methods/accessors also for consistency.

That said, while it’s a nice to have that I feel would constitute a beautiful default, this is not the hill I wish to die on :)

I’ve said my piece. I’ll let you standards folk do what you do and decide one way or another.

Hope you’re having a good week and that you and yours are safe and healthy during this time.