This content originally appeared on Go Make Things and was authored by Go Make Things
Yesterday, we learned about how to create libraries with the vanilla JS Class pattern. Today, I wanted to share my favorite JavaScript class features: private class properties.
Let’s dig in!
(Today’s post is an except from my updated course and ebook on Writing JS Libraries.)
What is a private class feature?
In our constructor pattern library, the validate()
function was a private function.
It wasn’t attached to the Constructor
or to the Constructor.prototype
, and could only be run from inside the IIFE. With our class pattern, validate()
is now a public method that developers can run. That’s not what we want.
let age = new Calculator(30);
// We don't want developers to be able to do this
age.validate();
In a JavaScript class, you can prefix properties and functions with a hash (#
) to denote them as private.
They’re still attached to the prototype (or the constructor, if you use the static
keyword), but cannot be accessed or run from outside of the class
object.
Because they’re attached to the prototype, we also have access to the this
operator, and no longer need to pass the instance
in as an argument.
/**
* Validate total before setting it
*/
#validate () {
// Avoid infinite loops
if (this._min > this._max) return;
// If below the minimum
if (this.total < this._min) {
this.total = this._min;
}
// If above the total
if (this.total > this._max) {
this.total = this._max;
}
}
We need to prefix it with a hash when running it as well.
/**
* Add two or more numbers together
* @param {...Number} nums The numbers to add
*/
add (...nums) {
// Loop through each number and do math
for (let num of nums) {
this.total = this.total + num;
}
// Validate the total
this.#validate();
// Return the instance
return this;
}
Private instance properties
We can also use this approach instead of the Object.defineProperties()
method to create read-only instance properties.
First, we’ll define our read-only properties, prefixed with a hash, outside of the contructor()
. Then, we’ll assign them as instance properties with a value inside the constructor()
function.
class Calculator {
#max;
#min;
/**
* Create the Constructor object
* @param {Number} num The starting total
* @param {Object} options Options and settings
*/
constructor (num = 0, options = {}) {
// Combine user options with defaults
let {max, min} = Object.assign({
max: Infinity,
min: -Infinity
}, options);
// Define properties
this.total = num;
this.#max = max;
this.#min = min;
}
// ...
}
Inside the #validate()
function, we’ll access them using the hash prefix instead of an underscore.
/**
* Validate total before setting it
*/
#validate () {
// Avoid infinite loops
if (this.#min > this.#max) return;
// If below the minimum
if (this.total < this.#min) {
this.total = this.#min;
}
// If above the total
if (this.total > this.#max) {
this.total = this.#max;
}
}
Now, when someone tries to overwrite or access those properties, they get an error message.
// Create a new instance
let age = new Calculator(30, {
max: 50
});
// Uncaught SyntaxError: Private field '#max' must be declared in an enclosing class
age.#max;
⏰ Last Chance! A new session of the Vanilla JS Academy started this week, but it's not too late to join. Sign up today and get 25% off registration.
This content originally appeared on Go Make Things and was authored by Go Make Things
Go Make Things | Sciencx (2022-07-20T14:30:00+00:00) Private class features in vanilla JS Classes. Retrieved from https://www.scien.cx/2022/07/20/private-class-features-in-vanilla-js-classes/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.