Motivation -
- use
private
keyword - Use class private and not instance private.
- Statically analysable.
Based on this issue - tc39/proposal-private-fields#14, there is a lot of interest in using the private
keyword and no sigils, and sigils cannot be avoided for multiple reasons specified in the FAQ.
Addressing some of the comments by littledan,
(Scroll to last for example)
class A {
private a, b;
}
Operator: ->
(thin arrow?)
class A {
private a;
get a() {
return this->a;
}
}
Class Private and not Instance private
Operator = ->
class A {
private a;
equals(other) {
return this->a === other->a;
}
}
At the accessing location -
class X {
private y = () => {}
z() {
w()
this->y() // <-- would be parsed as w();this->y();
}
}
At the declaration -
class Person {
properties = {}
private x
// would parse as how you'd expect
// because of the private keyword
}
class A {
private x;
foo() {
log(this->x); // x<A>
const thisA = this; // to access inside class B
class B {
private x;
constructor(a /* instance of class A */, b /* instance of class B */) {
// access private of A
thisA->x;
// access private of B
this->x;
// access private of incoming instance of A
a->x;
// access private of incoming instance of B
b->x;
}
}
new B(new A(), new B());
}
}
Can have a private field named x
and also a public field with the same name x
.
class A {
x = 0;
private x = 1;
constructor(x) {
this.x = x;
this->x = x;
}
}
- Other open issue - Call semantics - tc39/proposal-private-fields#85
// example from the original proposal
function getThis() { return this; }
class Test {
#fn;
constructor() {
fn = getThis;
}
fn1() {
return #fn();
}
fn2() {
return this.#fn();
}
}
const t = new Test();
t.fn1(); // ?
t.fn2(); // t
In this proposal,
function getThis() { return this; }
class Test {
private fn;
constructor() {
this->fn = getThis;
}
fn1() {
return this->fn();
}
fn2() {
return this->fn();
}
}
const t = new Test();
t.fn1(); // t
t.fn2(); // t
class A {
private a = 2;
a = 1;
private b() {
return this.a; // access public a
}
b() {
return this->a; // access private a
}
c() {
return this->b() + this.b();
}
d(other) {
return this->a + this.a + other->b() + other.b();
}
}
class A {
private const x = 1; // private constant value
const y = 2; // public constant value
}
Not sure how constructor passed arguments can be used to assign a const. So I'll leave it for later.
.
is for accessing public fields on any object->
for accessing private fields onthis
and any instance of the same class
class Point2D {
private x, y;
constructor(x, y) {
this->x = x;
this->y = y;
}
equals(p) {
return this->x === p->x && this->y === p->y;
}
}
A couple points on this proposal:
#
in both definitions and usages is intended to draw a connection between the two names, to make it easier to understand that they are referring to the same thing..#
rather than simply#
will let us keep open the possibility of using the#x
shorthand in the future without opening up an ASI hazardprivate
keyword now, we can still use theconst
keyword in the future.private const
fields can be initialized with, for example, arguments of the constructor. We need to work that sort of basic use case out before adding the feature.let
andconst
might seem to imply a single static private lexically-scoped value (as Allen proposed), which this is not.