Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Reviewed by Kent #1

Closed
kentcdodds opened this issue May 25, 2017 · 10 comments
Closed

Reviewed by Kent #1

kentcdodds opened this issue May 25, 2017 · 10 comments

Comments

@kentcdodds
Copy link
Member

Will close this when I've reviewed the proposal for stage-3

@kentcdodds
Copy link
Member Author

Things look good to go from my point of view, assuming my assumptions are correct based on #2. cc @littledan :)

@nodkz
Copy link

nodkz commented May 27, 2017

Doble-underscore is better than #
And for stage-3 this proposal gathers just 3 github stars, too few likers. Looks like that 3 guys conspired in a bar 😕

@chicoxyzzy
Copy link
Member

chicoxyzzy commented May 27, 2017

Double underscore is valid property identifier. It can't be used for private properties.

@chicoxyzzy
Copy link
Member

chicoxyzzy commented May 27, 2017

This proposal has 3 stars because it wasn't publicly announced yet

@kentcdodds
Copy link
Member Author

@littledan, I have another question. What would happen in this scenario?

class Counter extends HTMLElement {
  #x = 0;

  #clicked() {
    #x++; // what error will the user see if this function is called out of context?
    window.requestAnimationFrame(this.render.bind(this));
  }

  constructor() {
    super();
    this.onclick = #clicked; // note the lack of binding here
  }

  connectedCallback() { this.render(); }

  render() {
    this.textContent = #x.toString();
  }
}
window.customElements.define('num-counter', Counter);

@littledan
Copy link
Member

Not sure what you mean out of context. But say, from within Counter, you do #clicked.call({}), there are two possibilities for semantics:

  • TypeError when #clicked is invoked, due to the method not existing on the receiver {}
  • TypeError when #x is accessed from within #clicked (current spec text here)

Clarifying this question will be one of the necessary steps to specifying private methods. I'm leaning towards the first option at this point (after previously specifying the other one), but I'd be interested in more input. cc @allenwb @bakkot .

@allenwb
Copy link
Member

allenwb commented May 31, 2017

I recommend the second alternative as it is only private field access that have a hard branding requirement. Consider:

class S {
   #helper() { //assume some sort of "private method" semantics
       this.bar();
    }
    foo() {return #helper.call(this)}
    bar() {Console.log("bar(S)")};
}
class Sub extends S {
    bar() {Console.log("bar(Sub)")}
}
new S().foo();  //logs: bar(S)
new Sub().foo(); //logs: bar(Sub)

There is no reason that #helper should do a brand test that requires its this value to be an instance of S. It has no dependency on the private field shape of its this value. The method as written can successfully operate on any object that has a bar method and with dynamically throw (can't call undefined) if applied to on object without a bar method.

A private method brand check makes private methods less useful and would add unnecessary extra mechanism and overhead. As long as private field accesses are brand checked we should have to do any additional method level branding.

@kentcdodds
Copy link
Member Author

Thanks, that sounds ok to me @allenwb. I expect that we'll need to have folks weigh before or at the next meeting though.

@littledan
Copy link
Member

We'll have to discuss private methods in a separate topic; it's out of scope for this proposal. IMO both options are plausible choices.

@kentcdodds
Copy link
Member Author

I'm good with that decision. The proposal looks good to me. Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants