Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Classes are nothing new in programming, but their implementation in JavaScript is, well, weird. For anyone used to classes in other languages, you might think of them as blueprints from which new instances are copied. Additionally, you might think that these classes would offer public, private, and protected instance properties. In JavaScript, neither of these is true: new instances of objects have a prototypal inheritance relationship with their parents and there is no such thing as private or protected properties. In this article, I am going to dive into the latter point a bit further.
Note: If you enjoy this article, please give it a clap 👏 (or 50!) to help spread the word!
Why Private Fields in a JavaScript Class?
I started thinking about the issue of class instance privacy because I was creating a class-based data validation module (think form or JSON data validation). The idea is that you would be able to create a new validator instance whenever you had something new to validate (i.e., if you had two different forms on your website you might create one validator for each). The public API code to accomplish this might look as follows:
Looks great, right? Sure, why not. So as I was designing the actual validator module to make this vision come to fruition, I quickly realized I wanted to have some methods available within the module but not exposed in the public API. Namely, it became obvious to me that calling one of the rule-adding methods (e.g., mustBeValidEmail or minLength) should reference a private method called addRule that would add the rule to a private array of rules called validationRules.
I quickly realized I wanted to have some methods available within the module but not exposed in the public API.
It’s not that there’s anything super secret about the addRule method or the validationRules array, but moreso that there is no need to call/view them outside of the class, so why expose them and potentially cause errors?
Trying and Failing to Achieve Property Privacy
The title of this section is totally a spoiler alert: I tried several ways but ultimately failed to (satisfactorily) achieve property privacy. In this section, I’ll show you the ways I tried and why they just don’t cut it.
Attempt 1: Use an IIFE to create variables to which only the class has access.
An Immediately Invoked Function Expression (IIFE) is a great way to create a closure and essentially provide some statefulness within that closure. A notional example of how this would work is as follows:
Ah, beautiful. The validationRules array and the addRule function are now private as they should be. But this fails! Why? Because there is only one validationRules array ever created, meaning all Validator instances created will be adding validation rules to the same array. This will be chaos when it comes time to validate an object — all validation rules from all instances of the Validator class will be applied!
Attempt 2: Create new variables in the constructor function
This is an interesting approach that I found on StackOverflow. And it actually works, kind of. Sort of. Let’s take a look.
What’s going on here? Well, every time we create a new instance of the Validator class (i.e., using new Validator()), a new validationRules array and addRule function are created. Since the constructor function is creating a closure, this.prototype.mustBeValidEmail has access to these scoped properties. So this will actually work! But this fails! Why? Because creating new prototypal properties when every new instance is created is inefficient and simply wrong from an object oriented programming perspective.
Attempt 3: Just make the darn properties public
So this works, but it definitely doesn’t achieve privacy. I did, however, settle on using this method: unlike the others, it’s not hacky. It simply requires making sure these methods and properties are not documented as usable in whatever API documentation is generated and, of course, some tolerance for people running into errors because they decided to mess with these properties anyways (we all know how developers are).
Again, it’s readable, not hacky, and works.
Conclusion and A New Hope
So, in the end I have a module that works well but sacrifices some property and method privacy. It’s not ideal, but it works within the confines of what JavaScript offers today.
But… there’s hope yet for privacy in our JavaScript classes! Apparently I’m not the only one who thinks JavaScript classes could use private properties. The ECMAScript Technical Committee 39 is considering private class fields as I type! Soon, we’ll be able to designate private fields in our classes simply by prefixing them with the # symbol. I, for one, am really excited and I hope you are too.
Happy coding everyone!
Why I’m Excited for JavaScript Class Private Fields: A Case Study was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.