Explain Codes LogoExplain Codes Logo

Es6 class variable alternatives

javascript
class-fields
getters-and-setters
performance-implications
Alex KataevbyAlex Kataev·Jan 17, 2025
TLDR

Take advantage of static properties in ES6 classes for shared values not specific to instances.

class Example { static sharedValue = 'Shared among instances'; } console.log(Example.sharedValue); // Prints: Shared among instances

While ES6 doesn't offer a direct way to define class variables as you might find in other languages, the static keyword gives us a powerful tool for that purpose. Additionally, public class fields, part of the stage 3 proposal, can be initialized with the varName = value syntax in the class body.

Declaring instance variables

It's entirely possible to declare instance variables without clutter. Think of class fields or getters and setters as your clean-up crew, helping you maintain an uncluttered constructor:

class CleanCode { field = 'value'; // Public class field #privateField = 'hidden'; // Private class field (stage 3 proposal) get computedValue() { // Getters and setters that would make a janitor jealous return `Computed from ${this.field}`; // "I'm more calculated than Sherlock Holmes!" - computedValue } set field(value) { // Setters, a cleaner constructor's best friends this.#privateField = value; } }

Public class fields are like sassy properties with a mark of individuality; they are defined on the instance, not on the prototype. But stay tuned! There's always the chance Babel or TypeScript already got them covered, providing an elegant way to define class properties.

Management of sensitive information

Say you need to handle delicate information in your class. Many would relate this to handling delicate china, but ironically, here we wipe with static and not a soft cloth. Encapsulation using static getters and setters allows you to control access and mutations:

class SecureBox { static #internalKey = 'Secret'; // Like the hidden treasure at the end of a pirate movie static get key() { // Allowing peeking but no touchy! // Play out your grand heist return SecureBox.#internalKey; } static set key(value) { // You're under surveillance! // Placing security checks right here SecureBox.#internalKey = value; } }

Channel your inner Sherlock! It's especially useful in inheritance scenarios, where unique variable naming ensures no one crosses paths when they shouldn't.

Using WeakMaps for private variables

If managing garbage collection was an Olympic sport, WeakMaps would bring home the gold. They provide a way of defining private variables that clean up after themselves:

const privateMembers = new WeakMap(); class EcoFriendly { constructor(data) { privateMembers.set(this, data); // "Hide your kids, hide your wife!" - data } doSomething() { const data = privateMembers.get(this); console.log(data); // Base-jumping without the risk! } } let eco = new EcoFriendly('Hide yo data!'); eco.doSomething(); // Don't worry! It's just hide and seek for code!

Performance implications: Choice matters!

Class variable management is bit like a beauty pageant; every code block has its unique charms, but performance implications vary. Shared static properties are like the crowd's favorite, being efficient as they do not need to be redeclared for every instance. Individual instance fields take up more space, much like my wardrobe. Choose wisely!

Flexibility with dynamic class variable creation

For the elastic bands in the coding community that love dynamic extensions, there's a way! Your prototype properties can be your putty, allowing for instance variable creation outside of the constructor:

class Dynamic { static addMethod(name, method) { this.prototype[name] = method; // DIY methods, made to order! } } Dynamic.addMethod("sayHey", function(){ console.log("Hey!"); // Nicki Minaj would approve });