Skip to content

Instantly share code, notes, and snippets.

@joyeecheung
Last active March 19, 2020 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joyeecheung/6cf5f220943fe0cb2b46451d6400df88 to your computer and use it in GitHub Desktop.
Save joyeecheung/6cf5f220943fe0cb2b46451d6400df88 to your computer and use it in GitHub Desktop.
Intent to ship: JavaScript private methods and accessors

Contact emails

joyee@igalia.com, syg@chromium.org

Explainer

https://github.com/tc39/proposal-private-methods/blob/master/README.md

Spec

https://tc39.es/proposal-private-methods/

Summary

Currently, classes can already define private fields that are only accessible from within the class by using names starting with #. They can also define public fields, public methods and public accessors without the #. This feature completes the matrix by making it possible to define private class methods and accessors using the # syntax as well.

class Counter {
  #count = 0;

  get #value() {
    console.log('Getting the value');
    return this.#count;
  }
  #increment() { this.#count++; }

  equals(obj) { return this.#value === obj.#value; }
}

Private methods and accessors are not accessible outside of the class body:

const counter = new Counter();
counter.#increment();  // SyntaxError
const val = counter.#value;  // SyntaxError

And they can only be invoked on objects created from the class that declare them:

counter.equals({});  // TypeError

This intent to ship also includes private static methods and accessors to complement private static fields and public static methods/accessors:

class ClassCounter {
  static #count = 0;
  static get #value() {
    console.log('Getting the value');
    return ClassCounter.#count;
  }
  static #increment() {
    ClassCounter.#count++;
  }
  static equals(obj) { return ClassCounter.#value === obj.#value; }
}

ClassCounter.#value;  // SyntaxError
ClassCounter.#increment();  // SyntaxError
ClassCounter.equals({});  // TypeError

Motivation

To provide a way to encapsulate methods and accessors in classes, and to complement existing class features including private class fields and public methods/accessors.

Debuggability

Private instance methods and accessors on instances can be inspected in the debugger, and private static methods and accessors on classes can be inspected as well. They can also be invoked when the debugger steps into the class bodies.

Interoperability and compatibility risk

The ECMAScript proposal for private methods and accessors reached Stage 3 in TC39 in September 2017. Static class features with privates reached Stage 3 in May 2018.

This feature introduces new syntax that was previously a SyntaxError. The Web compatibility risk is low. Private class fields, which this feature builds on, have been shipped since M72.

Firefox: Public Support

Safari: In development (private methods, private accessors)

Edge: No signals

Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes

Is this feature fully tested?

This feature passes V8’s own mjsunit/cctest tests as well as all the Test262 tests labeled class-methods-private and class-static-methods-private.

Tracking bug

v8:8330

Link to entry on the Chrome Platform Status dashboard

https://www.chromestatus.com/feature/5700509656678400

Requesting approval to ship?

Yes.

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