JavaScript Class Privates

By  on  

One of my aspects of JavaScript that drew me to it as a young developers was that its syntax was loose and I could code quickly. As you gain experience as an engineer, you start to realize that some traditional coding structure is a good thing, even if it slows you down. Using Jest or TypeScript to add typing to your JavaScript can save you from maintenance headaches and unexpected errors, for example. While those are pre-compile tools to accomplish structure, we've traditionally employed vanilla JavaScript patterns to mock private variables and methods in JavaScript.

Did you know, however, that browsers and the JavaScript language support a specific syntax for creating private variables and functions in classes? Let's have a look!

Properties and methods on a class have always been considered public; to make a property or method private, add a # at the beginning of their name:

class Developer {
  name;
  #age; // Don't tell anyone my age!

  constructor(name, age) {
    this.name = name;
    this.#age = age;
  }
};

const David = new Developer('David', 38);

console.log(David.name); // David
console.log(David.age);  // undefined
console.log(David.#age); // Error!  Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class

David.name is available because name is public, while age is private because it's declared with a #. Similarly we can declare a private method with #:

class Developer {
  name;
  #age; // Don't tell anyone my age!

  constructor(name, age) {
    this.name = name;
    this.#age = age;
  }

  #getAgeInDogYears() {
    return this.#age * 7;
  }
};

getAgeInDogYears is only allowed to be called from within the class itself due to being declared with #. We can expose any information from within the class, public or private, if we make it available by public method:

class Developer {
  name = '';
  #age = 0;
  #ageInDogYears = 0;

  constructor(name, age) {
    this.name = name;
    this.#age = age;

    this.#ageInDogYears = this.#getAgeInDogYears();
  }

  #getAgeInDogYears() {
    return this.#age * 7;
  }

  log() {
    console.log(this.name);
    console.log(this.#age);
    console.log(this.#ageInDogYears);
  }
};

const David = new Developer('David', 38);
David.log();

// David
// 38
// 266

Adding a native syntax for declaring private class properties and methods is a welcomed addition to JavaScript; even better is that you can do so by simply adding a # to the beginning of its name.

Have you written code using private syntax in JavaScript? How was the experience?!

Recent Features

  • By
    Regular Expressions for the Rest of Us

    Sooner or later you'll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In...

  • By
    Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() - this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

Incredible Demos

  • By
    Style Textarea Resizers

    Modern browsers are nice in that they allow you to style some odd properties.  Heck, one of the most popular posts on this blog is HTML5 Placeholder Styling with CSS, a tiny but useful task.  Did you know you can also restyle the textarea resizer in WebKit...

  • By
    Basic AJAX Requests Using MooTools 1.2

    AJAX has become a huge part of the modern web and that wont change in the foreseeable future. MooTools has made AJAX so simple that a rookie developer can get their dynamic pages working in no time. Step 1: The XHTML Here we define two links...

Discussion

  1. Lynn Eriksen

    the way they have done private variables is garbage
    symptomatic of the slow pace and lack of creativity in the language these days

  2. It does feel hacky to me, to have added private properties to objects. We already *have* this, in the sense that closures contain private variables and functions but expose the privileged accessors.

    **Is** there a valid use-case for private properties on classes that isn’t cleaner and easier with Factories/Modules/closures?

  3. Hacky is fine as far as I’m concerned. I just want stuff to work as advertised. Was doing fine until Closure Compiler choked and I have to take a step backward to keep it going.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!