JS: How to create private class instance variables without using experimental features.

Photo by Taras Chernus on Unsplash

I had a friend tell me the other day that they figured out how to use an API. What they explained to me they instantiated class objects as required, but then they were manipulating properties and/or using functions that were prefixed with the _ character. As you may or may not know, there is an implicit contract dictating that properties with names beginning with _ shall not be accessed, altered, or even invoked. I believe that this implicit contract isn’t always sufficient and it isn’t defensive programming. People, like my friend, can and do break the implicit contract when consuming a library.

There happens to be a stage 3 proposal for private class variables, which is considered experimental, and I won’t be delving into it here. Even though it reached stage 3 in July 2017 it hasn’t been implemented widely yet. For example, Firefox hasn’t as per Can I Use. I believe we’ll be waiting at least another year before, or if, it is added to final specs. I don’t like using experimental features as the syntax can change at any time. Therefore, I have come up with a way to encapsulate private instance variables and functions that won’t be accessible by the consumers of the API by using a higher-order function and closures.

Below I’ve created two examples that are functionally the same, albeit the first example will have additional properties, but the contract is, no one should use or modify it. In the second example, I used Object.defineProperty() a cool function that, as its clever name indicates, defines a property on an object. You can define, setters, getters, and normal class variables (that can be any variable, object, or function). You can also specify whether a class variable is writable. I encourage you to read the documentation on it, and it’s sibling function Object.defineProperties().