DEV Community

Tanvir Azad
Tanvir Azad

Posted on

JavaScript Static vs Private: Explained by My Cat Oreo

Oreo is a black and white male cat who spends his days judging my code from the comfort of my desk chair (which he has claimed as his throne). Like most cats, he believes he owns everything - a perfect metaphor for understanding JavaScript's various scoping mechanisms!


Regular Variables and Methods: The Cat Features

Let's start with regular class variables and methods. Oreo's name and color are regular properties - anyone can access them.

class Cat {
  constructor(name, color) {
    this.name = name;
    this.color = color;
  }

  meow() {
    console.log(`${this.name} says: Meow!`);
  }
}

const oreo = new Cat("Oreo", "Black & White");
oreo.meow(); // Oreo says: Meow!
console.log(oreo.color); // Black & White - We can access and modify this property
Enter fullscreen mode Exit fullscreen mode

Static Variables and Methods: The Community Cat

Static variables and methods belong to the class itself, not instances of the class. This is not specific to Oreo but to all cats in the neighbourhood, like catCount and whatAreCats().

class Cat {
  static catCount = 0;

  constructor(name) {
    this.name = name;
    Cat.catCount++; // Incrementing the static variable
  }

  static whatAreCats() {
    return "Cats are liquid that sometimes behaves like a solid";
  }
}

const oreo = new Cat("Oreo");
const mittens = new Cat("Mittens");

console.log(Cat.catCount); // 2
console.log(Cat.whatAreCats()); // "Cats are liquid that sometimes behaves like a solid"

// console.log(oreo.catCount); // undefined
// oreo.whatAreCats(); // TypeError
Enter fullscreen mode Exit fullscreen mode

Private Variables and Methods: Oreo's Energy Level Management System

Private variables and methods (denoted with #) are only accessible within the class itself. Instances won't be able to use them. Oreo's energy level management system? Private.

class Cat {
  #energyLevel = 100;
  #recoverEnergy() {
    this.#energyLevel = 100;
    console.log(`${this.name} has recharged!`);
  }

  constructor(name) {
    this.name = name;
  }

  play() {
    console.log(`${this.name} is playing!`);
    this.#energyLevel -= 30;

    if (this.#energyLevel < 50) {
      this.#recoverEnergy();
    }
  }
}

const oreo = new Cat("Oreo");
oreo.play(); // Oreo is playing!
oreo.play(); // Oreo is playing!
oreo.play(); // Oreo is playing! Oreo has recharged!

// console.log(oreo.#energyLevel); // SyntaxError
// oreo.#recoverEnergy(); // SyntaxError
Enter fullscreen mode Exit fullscreen mode

Private Static Variables and Methods: The Secret Cat Society

Finally, we have private static variables and methods. Only the Cat class can keep track of all the naps. Individual cats like Oreo can take naps, but they can't directly access the total nap count.

class Cat {
  static #totalCatNaps = 0;

  constructor(name) {
    this.name = name;
  }

  // Instance method accessing private static method
  takeNap() {
    Cat.#incrementNapCount();
    console.log(`${this.name} is napping`);
  }

  // Private static method, can't be called by Cat.#incrementNapCount()
  static #incrementNapCount() {
    Cat.#totalCatNaps++;
  }

  // Public static method, Cat.getTotalNaps() is used to access this
  static getTotalNaps() {
    return `Cats have taken ${Cat.#totalCatNaps} naps so far.`;
  }
}

const oreo = new Cat("Oreo");
oreo.takeNap(); // Oreo is napping
oreo.takeNap(); // Oreo is napping

const mittens = new Cat("Mittens");
mittens.takeNap(); // Mittens is napping

console.log(Cat.getTotalNaps()); // Cats have taken 3 naps so far.

// console.log(Cat.#totalCatNaps); // SyntaxError
// Cat.#incrementNapCount(); // SyntaxError
Enter fullscreen mode Exit fullscreen mode

Summary: What Oreo Taught Us

  1. Regular Variables/Methods: Oreo's name and color are accessible to everyone.
  2. Static Variables/Methods: Oreo does not know about the totalCatCount or whatAreCats() as they are both static, so it is only known by the Cat class.
  3. Private Variables/Methods: Oreo's energy level and recoverEnergy() are hidden (private) and can only be accessed using a public method, play().
  4. Private Static Variables/Methods: Despite being static, the Cat class can't access the #totalCatNaps or #incrementNapCount(), since they are private static. takeNap() is to be accessed by Oreo and getTotalNaps() is to be accessed by the Cat class.

Practical Applications

Understanding these concepts is crucial when designing class hierarchies:

  • Use regular variables/methods when each instance needs its own unique data that should be accessible from outside
  • Use static variables/methods for functionality or data that applies to all instances collectively
  • Use private variables/methods to hide implementation details within instances
  • Use private static variables/methods to hide implementation details at the class level

Conclusion

Whether it’s Oreo’s public meow, his hidden energy levels, or the secret nap-tracking society only the Cat class knows about, each example helps draw a clear line between who owns what and who gets to know what. So the next time you're designing classes, think like Oreo: Some things are meant to be shared, others are best kept secret… even from the humans.


Disclaimer: No cats were consulted in the writing of this article.

Top comments (0)