Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active April 15, 2021 13:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rauschma/a4729faa65b30a6fda46a5799016458a to your computer and use it in GitHub Desktop.
Save rauschma/a4729faa65b30a6fda46a5799016458a to your computer and use it in GitHub Desktop.

Sketch: scoped private fields

So far, private fields are introduced as follows:

class MyClass {
  #privateField = 123;
}

I’d like to propose a small extension: scoped private fields.

Functional style (the proposal)

The following style is becoming popular in the JavaScript world. It benefits from scoped privacy:

private #data;

function createStringBuilder() {
  return {
    #data: '',
  };
}

function add(sb, str) {
  sb.#data += str;
}

function toString(sb) {
  return sb.#data;
}

New in this code:

  • The keyword private in the first line.
  • The ability to use private fields in object literals.

OOP style

As a slight downside, you now always need to use the keyword private:

class StringBuilder {
  private #data = ''; // keyword is required
  add(str) {
    this.#data += str;
  }
  toString() {
    return this.#data;
  }
}

On the upside, this gives you the freedom to widen the scope of privacy:

private #data;

class StringBuilder {
  #data = ''; // no keyword!
  add(str) {
    this.#data += str;
  }
}
function toString(stringBuilder) {
  return stringBuilder.#data;
}

Alternative syntax

Alternative syntax has been proposed:

  • Keyword private not needed for “normal” private fields.
  • Two keywords if you want to widen the scope of privacy: private and outer.

Example:

private #data;

class StringBuilder {
  outer #data = ''; // keyword is now required
  add(str) {
    this.#data += str;
  }
}
function toString(stringBuilder) {
  return stringBuilder.#data;
}

FP example:

private #data;

function createStringBuilder() {
  return {
    outer #data: '', // keyword is now required
  };
}

function add(sb, str) {
  sb.#data += str;
}

function toString(sb) {
  return sb.#data;
}
@ljharb
Copy link

ljharb commented Apr 13, 2021

No existing identifier is viable, because var _ = something at the bottom of the file hoists it ti the top, and there could be silent conflicts.

@basickarl
Copy link

basickarl commented Apr 15, 2021

But the whole point of the comment/code at the top was to tell the compiler to act in a specific way? Like bash's #!/usr/bin/env bash, am I missing something?

@ljharb
Copy link

ljharb commented Apr 15, 2021

That would be a new mode (like strict mode), and the committee is pretty firmly against ever adding another one. In addition, the refactoring hazard would be large, as code that works fine in one file would suddenly work differently in another.

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