Comments (12)
Yeah, sorry I updated the code.
The way that I think to teach #x
is to explain that it creates a special key only available to the class and gets used similar to a computed member.
Or in code form:
const Foo = (() => {
let x = createPrivateKey();
return class Foo {
constructor(x) { this[x] = x; }
print() { console.log(this[x]); }
};
}());
// no access to `x`
With this.#x
the behavior is fairly intuitive (ignoring how unintuitive this
is on its own), teaching this way is reinforcing how it reads syntactically.
But the #x
shorthand isn't intuitive in that way unless you know that this.
is implied.
Based on the feedback from my post, people are already confused by:
class Foo {
#x;
method(foo /*: Foo */) {
foo.#x
}
}
Because they think #x
is a variable that you're assigning to instead of a key that you have access to. I think that #x = 1;
reinforces the (incorrect) idea that it is a variable assignment to #x
instead of a key.
from proposal-class-fields.
Implicit shorthand creates confusion; I'd prefer static.x
as a shorthand for Foo.x
.
This would also be useful for static methods. Perhaps it should be part of a separate proposal, however?
from proposal-class-fields.
@thejameskyle (I assume you meant to write foo1.print.call(foo2)
.) Do you mean that the syntax implies the "lexically scoped value" intuition, and you'd expect 1
to be printed, even though it definitely prints 2
?
from proposal-class-fields.
from proposal-class-fields.
Let's pursue this in a separate proposal; public properties are just based on normal property access, so the accesses are also not necessarily from declarations.
Personally, I don't see the problem with Foo.x
. But closing because it'd be better to make a separate proposal.
from proposal-class-fields.
Do note that the reason behind my original suggestion (not static.x
, but direct access using x
and #x
) was to give a different (and more well-known) meaning to the shorthand syntax, since its existence in the private fields proposal is being criticized.
Shorthand syntax proposed here needn't be confusing, since it's already used by at least one language that I know of. Perhaps it can be thought of as block-scoped variable declaration (the block being the body of the class)
from proposal-class-fields.
OK, sorry for reading it too quickly.
This would work the same for private fields (and existing shorthand will have to be dropped in favour of this).
What do you mean by this? Most of the time private field shorthand will be used, it would be referencing instances, not static.
If we didn't drop the original shorthand: this is a completely orthogonal, different kind of shorthand; it's not really much of a counterpart of the private fields shorthand, since you'd expect static.#x
to work--it's along a different axis. An expectation that there be shorthand for everything sounds like an argument against private shorthand, not for it.
Shorthand syntax proposed here needn't be confusing, since it's already used by at least one language that I know of. Perhaps it can be thought of as block-scoped variable declaration (the block being the body of the class)
Actually, I think this "block scoped variable declaration" intuition is a little problematic. It makes it surprising that there is support for other.#x
as well. I hope users can learn that #x
is sugar for this.#x
, and the latter is the more basic form, as @thejameskyle's article explains it. cc @ashleygwilliams @wycats
from proposal-class-fields.
I'm a bit concerned about the shorthand syntax when methods are called with a different context.
class Foo {
#x;
constructor(x) { #x = x; }
print() { console.log(#x); }
}
let foo1 = new Foo(1);
let foo2 = new Foo(2);
foo1.print.call(foo2);
Going off the reading of the syntax alone it is ambiguous what this is going to log.
from proposal-class-fields.
This would work the same for private fields (and existing shorthand will have to be dropped in favour of this).
What do you mean by this?
My position on the shorthand syntax is that
- There should be only one way to access private property of the current object, and that should be
this.#property
since- It matches with our expectations of
#property
belonging tothis
as happens with normal object properties, e.g.this.property
- It is consistent with accessing private properties of other instances of same class in class methods like
foo.#property
- It matches with our expectations of
- The shorthand syntax should be dropped from the proposal
But simultaneously, I also got an idea that would perhaps be better suited as a different proposal altogether as ljharb suggested. The idea uses the shorthand syntax for something else - unqualified access for static private properties.
Demonstrating with a detailed example,
var someVariable = 10;
class Bar {
static publicProperty = 20;
static #privateProperty = 30;
#ownPrivateProperty = 40;
foo () {
#privateProperty++;
publicProperty++;
}
getPrivateValue() {
return #privateProperty;
}
baz() {
someVariable++;
}
ban() {
this.#ownPrivateProperty++;
}
getOwnPrivateValue() {
return this.#ownPrivateProperty;
}
bat() {
nonExistentIdentifier++;
}
}
var o = new Bar();
o.foo();
assert.equal(Bar.publicProperty, 21);
assert.equal(o.getPrivateValue(), 31);
o.ban();
assert.equal(o.getOwnPrivateValue(), 41);
o.baz();
assert.equal(someVariable, 11);
o.bat(); // throws ReferenceError because it neither found a lexical binding nor a static property with the name nonExistingIdentifier
Instead of the shorthand #property
referring to this.#property
it refers to the static
private property of the class Bar
from proposal-class-fields.
@peey Are you saying that you expect that if the #foo
shorthand exists to get static private fields within a static method, then you could use foo
to refer to a public static field, by virtue of analogy?
(In your example, you meant to put static
in front of getPrivateValue() {
, right? Otherwise, you'd get an undefined-is-not-a-function TypeError before reaching the part you're calling unintutiive.)
from proposal-class-fields.
@littledan I have fixed the code example. I meant to use getPrivateValue
as a regular method, not a static method, so I've fixed where I incorrectly used it as assert.equal(Bar.getPrivateValue(), 31)
to assert.equal(o.getPrivateValue(), 31)
I'm proposing that
#foo
shorthand should always refer to the static property#foo
of a class, be it in a static method or a non-static method- if
foo
is a public static field for a class, thenfoo
should refer to the static propertyfoo
of that class, be it in a static method or non-static method
from proposal-class-fields.
Let's take these two suggestions separately:
- For
#foo
on a static member always "working", regardless of the receiver: This is basically to say that#foo
acts like a lexically scoped variable, rather than a member of the constructor. This idea actually bares a lot of resemblance to an open question for private methods (which I still need to write up)--should private methods type-check their receiver, or "just work" since the value is always the same? I think we could decide either way, and if we go down the second path, it'd be reasonable to do something similar for private static fields. - For public static fields, it's a bit different. Because it's an ordinary public property, code outside the class can change it, or even define a getter/setter--what effect should that have? Should it be possible for two things to get out of sync? And you might imagine that whatever is done for public static properties works for public methods too--should we add that? Given the complexity and cross-cutting issues to make something consistent, I think the motivation for this shorthand would have to be explained a bit more fully to add this feature.
from proposal-class-fields.
Related Issues (20)
- Class fields are a time waster. HOT 7
- Motivation for PrivateFieldAdd type error? HOT 5
- Interaction with Integrity Levels? HOT 4
- private field and protected field HOT 1
- Clarify what the context (`this`) for fields declared as anonymous functions will be in the spec. HOT 2
- Inferred function names for number/bigint fields aren't handled right HOT 2
- [Suggestion] Consider to use time proof solution with private and protected keywords HOT 39
- Private fields breaks POI HOT 35
- Support for privates in object literals? HOT 3
- Class composition HOT 3
- [[Define]] semantics causes libraries to lose performance. HOT 2
- class fields with [[Define]] semantics are much slower than with [[Set]] semantics. HOT 3
- [[Define]] semantics necessitate workarounds HOT 7
- Properties without initializers can create some headache in "real-world" scenarios. HOT 14
- Why are #private fields not source-positional? HOT 22
- Statement of our opinions on class fields and its related package of proposals HOT 2
- Proxy nested inside of the Prototype Chain HOT 2
- Please Don't Do That. HOT 8
- Why are class fields so slow? HOT 2
- Constructor arguments with object destructuring HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from proposal-class-fields.