View profile

Public Class Fields: A Better Way to Define Methods in JS?

Public Class Fields: A Better Way to Define Methods in JS?
By Mastering JS Weekly • Issue #81 • View online
JavaScript classes have a simple syntax for defining class methods, functions that every instance of the class has.

Basic example of defining a method
Basic example of defining a method
Unfortunately, class methods still suffer from the same function binding issues as normal JavaScript functions. The value of `this` in the `area()` function is equal to the object that `area()` is attached to when you call `area()`. So, if you call `area()` without a `.`, `area()` will return NaN because `this` is undefined.
Oops!
Oops!
Public Class Fields Got Me Out of a `bind()`
Recently, I was working on a project that exposed an `init()` function that created several class instances. The `init()` function returns an object that contains wrappers around some of those methods.
For example, suppose you had an `initViewport()` function that created a new Rectangle. And that function returned an object with a function to calculate the viewport’s area.
`area()` is bound to the wrong object!
`area()` is bound to the wrong object!
The usual way to fix this problem in JavaScript is to explicitly `bind()` the area method in `result` using `rect.area.bind(rect)`. However, it is easy to forget to call `bind()`, and easy to overlook this mistake in code review.
With public class fields, there’s an alternative approach that doesn’t require `bind()`. You can instead define `area()` as an arrow method as shown below.
One weird trick™ to never write `bind()` again
One weird trick™ to never write `bind()` again
Arrow methods mean `area()` is always lexically bound to an instance of `Rectangle`. No need for `bind()`, `area()` always has the correct value of `this`.
Arrow method in action: correct `this` with no `bind()`
Arrow method in action: correct `this` with no `bind()`
Even better, arrow methods retain the method `name` property and keep the method name in stack traces. This behavior is surprising, because arrow functions are supposed to be anonymous. But it looks like arrow methods have names, which makes them a viable replacement for `bind()`.
Neat stack traces are a pleasant surprise
Neat stack traces are a pleasant surprise
Takeaways
Class fields are a new addition to JavaScript - they just hit stage 4 in 2021. However, browser support is pretty good, and Node.js has supported class fields since v12. I intend to start using this syntax for all class methods going forward, unless I find a reason not to.
Try out arrow methods. They provide a meaningfully better way to define class methods in JavaScript.
Most Recent Tutorials
Create a Chart with 2 Y Axes in ChartJS - Mastering JS
Hide the Tooltip in ChartJS - Mastering JS
Set Axis Label Color in ChartJS - Mastering JS
Set Chart Size with ChartJS - Mastering JS
String replaceAll() in JavaScript - Mastering JS
What We're Reading
CSS-Only Carousel | CSS-Tricks - CSS-Tricks
Did you enjoy this issue?
Mastering JS Weekly

Pragmatic web development. No bloatware allowed!

In order to unsubscribe, click here.
If you were forwarded this newsletter and you like it, you can subscribe here.
Powered by Revue