tc39 / tc39/proposal-private-declarations

Add `protected #x`

Open
#6 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
26
Forks
2
Avg merge
1m
Merged PRs (30d)
2

Description

What about adding protected #x notation? It seems to be natural extensions to this proposal, since majority of developers will expect to have public/private/protected keywords used in same fashion and might be surprised if something is missing (it also appliable to #5).

protected keyword might solve positional vs closure problem described in https://github.com/tc39/proposal-class-fields/issues/60

Let's make protected the same as private whith one exception, private belongs to closure scope, while protected belongs to lexical scope. To illustrate:
private

function mixin(klass) {
  private #x;
  return class extends klass {
    #x = 1;
    add(obj) {
      return this.#x + obj.#x;
    }
  }
}
const A = mixin(class {});
const B = mixin(class {});
const a = new A;
const b = new B;
a.add(a); // works
a.add(b); // throws, since their `#x` are different, because created per closure scope

protected

function mixin(klass) {
  protected #x;
  return class extends klass {
    #x = 1;
    add(obj) {
      return this.#x + obj.#x;
    }
  }
}
const A = mixin(class {});
const B = mixin(class {});
const a = new A;
const b = new B;
a.add(a); // works
a.add(b); // works, since their `#x` are the same, because created per lexical scope

protected could be extremely useful for some types of mixins, while others are still possible.
BTW, @ljhard, this type of protected actually does protect something 😉

It works even better with #1. For example:

function mixin(klass) {
  return class extends klass {
    protected #x = 1;
    add(obj) {
      return this.#x + obj.#x;
    }
  }
}

Addition

It might be extended a little bit in root-level lexical scope. Consider this:

export class A {
  protected #x;
}

Without any specific behavior protected at root-level lexical scope will behave exactly the same as private, so previous code will be euqal to following:

export class A {
  private #x;
}

But to make it closer to meaning of protected from other languages, we may change this a little bit, so code will be equal to:

export private #x;
export class A {
  #x;
}

P.S.

I'm not sure what term will be preferable for this proposal: lexical scope or outer closure scope. They probably might have slight difference, but I don't see how it can affect this proposal.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the proposed protected #x examples in this issue, then compare them with the referenced #5 and class-fields issue #60. A complete contribution would resolve the lexical-scope semantics and produce an agreed proposal for protected declarations.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.