With ES6 classes, we have getter and setter properties, but no field option (or at least that I know of).
With Object.defineProperty
, you can set them with the value
property. If at all, how do you do the same with classes?
I'm aware it can be done in the class constructor, but if possible I'd like for it to be separate.
With ES6 classes, we have getter and setter properties, but no field option (or at least that I know of).
With Object.defineProperty
, you can set them with the value
property. If at all, how do you do the same with classes?
I'm aware it can be done in the class constructor, but if possible I'd like for it to be separate.
Share Improve this question edited Oct 29, 2020 at 20:26 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Apr 4, 2017 at 10:41 SpedwardsSpedwards 4,49216 gold badges59 silver badges119 bronze badges 8- 1 I don't understand this question. Can you give an example of how "it can be done in the class constructor" so we can see what you are looking for? – lonesomeday Commented Apr 4, 2017 at 15:27
-
@lonesomeday In the class constructor,
this.whatever = 'someValue';
– Spedwards Commented Apr 4, 2017 at 15:54 - 1 So you mean object properties? "Class field" is not a concept that exists in JS. – lonesomeday Commented Apr 4, 2017 at 16:22
- Yes... They're the same thing regardless of language. @lonesomeday – Spedwards Commented Apr 4, 2017 at 16:23
- 1 Initialisation of instance properties should be done in the constructor. What do you think is wrong with that? Why do you want to do it "separate"? – Bergi Commented Apr 4, 2017 at 17:12
2 Answers
Reset to default 6You say above "they're the same thing regardless of language".
Well, yes and no.
Yes, there are obvious relations between programming languages, but Javascript/ECMAScript has some unusual features. Don't just e in expecting concepts to translate exactly.
The key thing is that Javascript is not class-based, even though it does not have class-like syntax. It is prototype-based. This means you can declare any property on any object. You don't need to include it in a class declaration.
For this reason, "class fields" were not included in the ES6 standard. It was expected that you would include them in the constructor
method, as is normal in pre-ES6 Javascript.
There is a proposal to create public class fields. These would look something like this:
class Dog {
constructor(name) {
this.name = name;
}
bark() {
console.log('woof');
}
tail = new Tail()
}
You could then have code that looked like this:
let benji = new Dog('Benji');
let rover = new Dog('Rover');
console.log(benji.bark === rover.bark); // true
console.log(benji.tail === rover.tail); // false
The key thing is that every "instance" has the same method. However, each "instance" has a different property. This is the distinction that explains why this syntax was not originally included.
As a proposal this is not currently supported. It can be used using transpilation, however. Babel.js (with, as I write, the Stage 2 preset transpiles the above code into this:
class Dog {
constructor(name) {
this.tail = new Tail();
this.name = name;
}
bark() {
console.log('woof');
}
}
Class fields are now a stage 3 ECMAScript proposal and are already supported in current versions of Chrome and in Node.js 12. The proposal also references static fields.
class MyClass {
static createdObjects = 0;
objectNumber = MyClass.createdObjects++;
}