Skip to content

Add protected #x #6

Description

@Igmat

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 tc39/proposal-class-fields#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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions