Introduction
While using JavaScript, you might be dearly missing our friend "private" from statically-typed languages like C#, C++, and Java. Using a little finesse, we can actually achieve true encapsulation using local variables in vanilla JavaScript (ES6) classes.
There are many instances where we want to hide an object's properties from public view. In other words, we only want to allow the object's methods to operate on these properties. But how can we do this in a dynamically-typed language like JavaScript?
To do this, we can utilize block scoping using const or let within the class constructor, and provide public methods that can return or operate on these encapsulated variables.
Example - The Counter Component
For this example, let's say we're making a Counter component. This will be a reusable component that encapsulates a count and allows the user to increase or decrease the counter linearly. The user should be able to look at the count variable, but they shouldn't be able to reach in and change it by hand.
Without Encapsulation
Our first attempt could look something like this,
- class Counter {
- constructor(startAt = 0){
- this._count = startAt;
- }
- increase(){
- ++this._count;
- }
- decrease(){
- --this._count;
- }
- get count(){
- return this._count;
- }
- }
This will work, but this._count isn't really encapsulated properly. The consumer of this class could easily reach in and change the value.
In order to fix this, we'll have to change this class around a bit.
Encapsulating the Component
First, instead of making _count an object-level property, we'll restrict it to the scope of the constructor, and add an appropriate getter for it. We'll still use the ES6 get syntax for ease-of-use

Steven CooperPosted May 23, 2021, 10:47 PM
It's a neat trick but ultimately what's the point? The getCount function is still publicly exposed so why create the count getter in the first place? You can just call the getCount() function. A better use for encapsulation is extracting functionality into private methods to keep your functions small and manageable which is something you can't really accomplish with this. The best I've been able to do is define sub-functions as const variables inside of my public functions but you still end up with a single function definition that's really big and unsightly.