2020-02-05
|~3 min read
|590 words
When I was first learning about Javascript (so, several months ago), I found this article from Douglas Crockford about private variables and members in Javascript. In it, he begins with the assertion that “JavaScript is the world’s most misunderstood programming language” and then proceeds to claim that “JavaScript objects can have private members” and takes the rest of the article as an opportunity to demonstrate how.
More recently, however, I found an blog post from Tsh.io highlighting several of the features that landed with Node v12. Among the list was private class fields and methods.1
Private class fields are a Stage 3 proposal from TC39, which means they’re still experimental.
However:
This proposal replaces many of the conventions the Javascript community has found in the past to emulate private methods and fields in the past such as an _
prefix (e.g., _privateVar
), closure, proxies, etc. (for more of these approaches, see the resources below).
Let’s look at an example using a Rectangle
class.
class Rectangle {
width = 0
#height = 0
constructor(width, height) {
this.width = width
this.#height = height
}
area() {
return this.width * this.#height
}
}
Now, let’s instantiate that class and try accessing its properties:
let rect = new Rectangle(4, 5)
console.log(rect.area()) // 20
console.log(rect.width) // 4
rect.#height = 6console.log(rect.#height)
Things go swimmingly until the last two lines. If either of them are present, you’ll get an error:
SyntaxError: Private field '#height' must be declared in an enclosing class
And while dot notation doesn’t work, bracket notation does not either:
console.log(rect["#height"]) // undefined
The TC39 proposal also includes support for private methods:
class Rectangle {
width = 0
#height = 0
constructor(width, height) {
this.width = width
this.#height = height
}
#increase(factor) {
this.width = factor * this.width
this.#height = factor * this.#height
}
area() {
return this.width * this.#height
}
enlarge(by) {
this.#increase(by)
}
}
Note, however, that this is not yet supported in Node (as of V12.13).
When it comes to private fields and methods in Javascript, there are a variety of approaches and opinions. Douglas Crockford is on one side proposing we’ve have them since 2001. At the same time TC39’s proposal is pushing us toward a more declarative future.
In any case, I’m excited about the inclusion of private variables within Node 12 (and am continually grateful to the folks behind Babel for allowing the community to push forward with experimental syntax). It’s not yet clear what the final spec for private variables will look like (it’s been in committee for several years at this point), but it’s clear we’re still making progres - that alone is exciting and inspiring enough to make me want to keep learning!
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!