I have the following CoffeeScript code:
class Person
secret = 0
constructor: (@name, @age, @alive) ->
inc: -> secret++
Which compiles to the following JavaScript code:
var Person;
Person = (function() {
var secret;
secret = 0;
function Person(name, age, alive) {
this.name = name;
this.age = age;
this.alive = alive;
}
Person.prototype.inc = function() {
return secret++;
};
return Person;
})();
Currently secret
is shared between all instances of Person
. Is there a way to make secret
a private instance variable in CoffeeScript?
Private instance fields are declared with # names (pronounced "hash names"), which are identifiers prefixed with # . The # is a part of the name itself. Private fields are accessible on the class constructor from inside the class declaration itself.
In its current state, there is no “direct” way to create a private variable in JavaScript.
In a JavaScript class, to declare something as “private,” which can be a method, property, or getter and setter, you have to prefix its name with the hash character “#”.
Short answer, no, there is no native support for private properties with ES6 classes. But you could mimic that behaviour by not attaching the new properties to the object, but keeping them inside a class constructor, and use getters and setters to reach the hidden properties.
I figured out a solution. I am not sure if this is the best solution, so I am still open to others.
CoffeeScript:
class Person
constructor: (@name, @age, @alive) ->
secret = 0
@inc = -> secret++;
JavaScript:
var Person;
Person = (function() {
function Person(name, age, alive) {
var secret;
this.name = name;
this.age = age;
this.alive = alive;
secret = 0;
this.inc = function() {
return secret++;
};
}
return Person;
})();
There is no concept of private members in CoffeeScript as there is none in JavaScript. There are local variables, which you do utilize well in your own solution, but while your solution does hide the secret
variable from anything outside of a constructor
function, it also introduces an overhead of redeclaring the inc
method on every instantiation of a class Person
.
A mistake very common in JavaScript community is trying to project inexistent features of other languages on it, which an attempt of mimicing private members is obviously a case of. There's no such concept in it and thinking deeper you'll conclude that it would be just unnatural to an extremely loose dynamic environment which JavaScript is.
So don't waste your time and performance of your application on implementing inexistent constructs. Just concentrate on solving your problem - not the problems of lacking language features.
Now ask yourself: what is so hurtful in having all members public?
Taking everything said into account the ultimate solution would be:
class Person
constructor: (@name, @age, @alive) ->
@secret = 0
inc: -> @secret++
While it won't truly hide them, the convention is to prefix "private" members with an underscore. The idea here is that folks consuming this should assume that such members are implementation details and are advised not to use them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With