If you're developing in a dynamically-typed language like JavaScript or Python, you may be dearly missing our friend "private" from statically-typed languages like C#, Java, and C++.
I'm sure plenty of developers know about this already, but I feel like no one ever talks about this. In all my years of studying programming, every time I've searched for how to achieve true encapsulation in JavaScript, the same answer always appears:
You can't.
Wrong!
If your dynamic-language-in-question has the concept of a class and the concept of self-referential instance variables like this or self, then you can achieve this result.
Let's cut to the chase.
For this example, let's say we have a Counter component. Ideally, this would hide the actual count variable from the code that consumes it.
class Counter {
constructor (startAt = 0){
this.count = startAt;
}
}
This code cannot be encapsulated because now this.count is publically accessible.
We can utilize scoping rules to achieve true private accessibility. So instead, we will use let to constrain the scope of count to the constructor, and add our behaviors using this.
class Counter {
constructor (startAt = 0){
let count = startAt;
this.getCount = function(){
return count;
}
this.increase = function(){
++count;
}
this.decrease = function(){
--count;
}
}
}
You can even use the arrow-function syntax to shorten it.
class Counter {
constructor (startAt = 0){
let count = startAt;
this.getCount = () => count;
this.increase = () => ++count;
this.decrease = () => --count;
}
}
Finally, you could even add a convenience getter for the public-facing API
class Counter {
constructor (startAt = 0){
let count = startAt;
this.getCount = () => count;
this.increase = () => ++count;
this.decrease = () => --count;
}
get count(){
return this.getCount();
}
}
Using this component is simple, and the underlying data is truly encapsulated.
const counter = new Counter();
counter.increase();
console.log(counter.count);
Although it's a little bit more code overall, you only need to do this for the data that you want true private accessibility for.