August 14th, 2023 × #javascript#webdev#decorators
JS Fundamentals - Decorators
Scott and Wes discuss JavaScript decorators - what they are, how to use them, their current status, and potential future use cases.
- Overview of decorators in JavaScript
- Decorators currently at stage 3, implemented in Firefox but not yet Chromium/Safari
- Difference between TypeScript decorators and spec decorators
- Potential for third version of decorators in the future
- Extensions to decorators beyond classes
- Decorators wrap/extend class functionality
- Decorators add functionality to classes/properties/methods
- Examples of decorator use cases - logging, reactivity
- Decorators reference a function
- Can decorate class, methods, getters/setters
- Use cases - logging, initialization
- Other use cases - reactivity, event listeners
- Initializing web components with decorators
- Decorators similar to higher order functions
- Wish list: decorators for functions in React
- How decorators are evaluated and called
- Parameters passed to decorator functions
- Applying decorators syntax
- Defining decorators as normal functions
- Syntax for decorating classes vs properties
- Syntax likely required, not just convention
- Auto accessors syntactic sugar for private variables
- Benefits of auto accessors with decorators
- Example of auto accessor decorator
- Benefits of getters/setters to end user
- Plan to explore classes more due to decorator power
- AngularJS vs Angular version clarification
- npm installs for AngularJS vs Angular packages
- Many old AngularJS apps not using npm
- AngularJS 1.2 released 10 years ago
Transcript
Announcer
Monday. Mon Monday. Hey. Open wide dev fans. Get ready to stuff your face with JavaScript, CSS, node modules, barbecue tips, get workflow, breakdancing, soft skill, web development, the hastiest, the craziest, the tastiest TS web development treats coming in hot. Here is Wes, Barracuda,
Wes Bos
Boss, and Scott
Scott Tolinski
key. Welcome to Syntax.
Scott Tolinski
On this Monday, hasty treat, we're gonna be talking about decorators.
Scott Tolinski
We're gonna be diving into the current status of decorators in JavaScript.
Overview of decorators in JavaScript
Scott Tolinski
We're gonna be talking about what they are, how to use them, and maybe some of the finer points and maybe even future points of what decorators behold to us.
Wes Bos
Hey, everybody. Excited to talk about decorators finally. I feel like we've mentioned them on the show for years years years, and they are.
Wes Bos
Is it is it safe to say they are finally here? I mean, they're here ish.
Scott Tolinski
And and so the current status of decorators is they are currently in stage 3.
Decorators currently at stage 3, implemented in Firefox but not yet Chromium/Safari
Scott Tolinski
Firefox is implementing them as we speak. There is an open issue about it. But I believe Before they go to stage 4, they need to have 2 independent browsers implementing them. So, as far as I know, I haven't seen anything about Chromium or Safari implementing these. So we will see When decorators will arrive, but you can use decorators in many senses.
Scott Tolinski
Many times people are using different plug in systems whether it's Babel or whatever. And now the actual decorator spec will differ quite, well, maybe not quite a bit. It differs a bit from the one that's available in TypeScript or the one that's available in Babel or any of the means in which you tried to use decorators.
Scott Tolinski
But we're gonna be mostly talking about class decorators because that is what is coming to the browser in stage 3. Are are they different than
Wes Bos
The are the TypeScript versions different than the the spec ones? Because I know there was TypeScript decorators for a long time, and then TypeScript deprecated but kept it around.
Wes Bos
And then they've implemented the new decorators version. I I was under the impression that that was the Ecma Decorators, but is it different? Well, I have to double check. You know what? I I was reading through the,
Difference between TypeScript decorators and spec decorators
Scott Tolinski
through the proposal here. And there's a whole section about how does it differ from, babble decorators? How does it how is it differ from TypeScript creators. How does it and so they they address all of those.
Scott Tolinski
And how does it differ from TypeScript decorators? Could have been referring to the previous implementation of that. Although it doesn't necessarily explicitly say that. It just says how do these differ from the TypeScript version of Deckorators?
Wes Bos
So it's TypeScript 5 came out with the ECMA script decorators, which is the one we're talking about today. Okay. So never mind that a little bit weird because they, like, had their own version. Right. And then they scrapped it. A lot of the Versus code code base is built using it as well, which is Kind of tricky, but luckily, they have the new version, which which is funny that they, like, went all in on it because it's it's not done yet, right? Yeah. There's a possibility that it could change.
Wes Bos
Probably not, but it happened to them once before. So
Potential for third version of decorators in the future
Scott Tolinski
Are we gonna have a 3rd version? Yeah. I I have no idea. And it really seems like this is going to be it in terms of decorators, at least as they're added. Yeah. And You know what? It is really interesting. It's an interesting API. And I was under the false assumption that once Decorators were added. They were going to be added for everything, but it really seems like it's only classes for now With the potential for adding decorators to literally anything pretty much.
Wes Bos
Yeah. So there's a on the TC 39 decorator proposal, there's a link you have here to extensions, and they show everything as like a function decorator, a const decorator.
Extensions to decorators beyond classes
Wes Bos
So you could say let at deprecated x equals one. So you can mark variables as being deprecated. It's kinda cool. Mhmm. There's some interesting stuff that, you know, I think about, like, even in Svelte, You create like a writable,
Scott Tolinski
but maybe you could create a writable by using a decorator instead of importing writable. And then you're just, you know, at writable or something on a variable.
Scott Tolinski
And then you have access to initializing it, or stepping in the way of it kind of deal. I don't know. It's all an interesting world. Be their way, the classes based decorators are kind of a a largest API in general Because it turns out there's kind of a lot you can do with decorators.
Decorators wrap/extend class functionality
Scott Tolinski
And as a non object oriented, programmer I mean, you know, I I understand OOP, but I I don't I don't think I write object oriented code that much. It would it's been really fascinating for me to dive into some of this stuff in terms of, the use cases Get around, you know, getters and setters and Mhmm. Those types of things. So, decorators as simply put, It's a function that decorates your class or any of your properties in your classes And then potentially, like, we mentioned other things. And by decorating, it's adding additional functionality.
Scott Tolinski
It's wrapping it. It's Able to extend its functionality. It's able to initialize it with data or do things that are surrounding that data or surrounding that object.
Examples of decorator use cases - logging, reactivity
Wes Bos
Yeah. So you may have you probably have seen it in Angular has used it for a long time.
Wes Bos
Lit for web components has used that for a while. The way that it works is you put an at on top of the thing that you are decorating, and then you give it a name.
Wes Bos
And that is corresponding to a function that exists somewhere else in your code base, very similar to how, Like, tag template literals on strings.
Decorators reference a function
Wes Bos
You know how you can, like, tag a a back ticks? That's a function as well.
Wes Bos
So decorators in themselves are referencing a function somewhere else. So you can decorate an entire class.
Wes Bos
You can decorate individual methods.
Can decorate class, methods, getters/setters
Wes Bos
You can decorate the getter or the setter of a variable, as well as, just properties that are inside of that. So private, public, static,
Scott Tolinski
properties that are inside of your class. So it's kind of cool because you could decorate the whole thing or individual methods or properties that live inside of that class. Yeah. And and what are some potential use cases for for decorating something? Well, it kind of what it does is if you can imagine, it kind of sweeps functionality under the rug to hide it underneath essentially like a tech.
Scott Tolinski
So you could use, like a log decorator to log anytime a variable has changed inside of its getter and etcetera or any time it's being updated.
Use cases - logging, initialization
Scott Tolinski
You could log the initialization of a class, if the class is initialized.
Wes Bos
Yeah. The logging one is, at least right now, it seems to be one of the most handy ones to me because You can write a single log function and you just pop at log on top of any method that you want, and you're not explicitly going into the method and adding a bunch of console logs or debugger points or anything like that. You can simply just say, Yeah. Exactly. Yeah. Because it's sometimes like, oh, man. I gotta add all these console logs and make sure I remove them. And this is really nice where you could just tag something with at log, And then you can say your your log you could leave them in if you want, and your log function could say, if we are in development, then go ahead and and log out what you need.
Other use cases - reactivity, event listeners
Wes Bos
Another kind of cool use case is like event listeners or like reactive data.
Wes Bos
So If you are creating a component and you have some state or some properties on there, you can put reactive on top of it. This is what I think Angular does. I think it's, lit does this as well. Basically, if there's a a variable that you want to explicitly watch for it to change, tag it with at reactive, and the that function will then Watch that variable to change, and when it changes, it will do whatever you want. Likely update the part of the code base that contains that variable, but it could fire an event as well. You name it. Yeah. And in some of the interesting use cases that I've seen too are initializing like a web component.
Initializing web components with decorators
Scott Tolinski
You could, add a a, like, component name to a a decorator to then initialize it in the browser once this thing is being loaded.
Wes Bos
Yeah. If you have used, like, a higher order function before. Yeah. Higher order function. Perfect.
Decorators similar to higher order functions
Wes Bos
A function that takes a function as an argument.
Wes Bos
Generally what that's doing is it's taking in a function, it's Transforming it in some way. It's adding some data to the scope. It's doing whatever it needs to do and then At the end of the day, running it. Deckorators, at least to me, they seem kind of similar in that, okay, I have this method that save some data.
Wes Bos
If I want to be able to modify or check what variable is being accessed or another very common use case is validation. Like, if you want to somebody is setting their, let's say me and Scott had a game, and you're setting a score to x, y, and z. You that method could just set the score, And then all the validation inside of that, make sure it's a number, make sure it's allowed, make sure it's, only 1 more than the previous score. All of that sort of logic could live in a separate function. And it's kind of nice to be able to if you want to be able to separate the saving data from the actual validation, especially if you want to reuse that validation logic across multiple methods or multiple classes.
Wish list: decorators for functions in React
Scott Tolinski
Yeah. You know, this is in times like this, I I get sad that, you know, these aren't coming to functions right away because one of the times that I really like to use decorators, but I did. It was in a function context in React world as essentially a higher order function or higher order component, you know.
Scott Tolinski
I would just use a dirt decorator to load a script or to load some data or something to that degree.
Scott Tolinski
And I I found that experience to be really nice, but seeing as how, React components are now only functions pretty much that is not looking like something that we'll be able to do for a little while. So to define a decorator, you're essentially just writing a function. There's nothing special to this function beyond essentially the parameters that are are passed into the function. Right? But so it's a function.
Scott Tolinski
So when the code loads, the decorator expression is first evaluated, then the decorator function is called during the class definition.
How decorators are evaluated and called
Scott Tolinski
After all of the methods within the class have been evaluated, but before The constructor and the prototype are put together. K. This this this is like deep stuff for people who who care about this. But, basically, at that point, When they get called, when the the decorator gets called, which is now, it gets 2 parameters. 1 of which Is the value being decorated and the second is a context object containing a bunch of information about the thing being decorated.
Parameters passed to decorator functions
Scott Tolinski
So you get access to, like, what kind of a decorator it is, name access, whether or not it's private, whether or not it's static Mhmm. And an add initializer method that you can then, to add an initializer on this value.
Applying decorators syntax
Scott Tolinski
After that, the decorators are applied and
Wes Bos
it modifies the class. Yeah. So it's it's kind of interesting that it it, like, happens when you Like the code is evaluated. Scott said, like exactly when it happens, but it doesn't run when you like run a method. It runs when the code is is evaluated. And if you want to run custom functionality when the method is run, that's where you then return a function from the decorator. And that sort of just queues it up to say, all right, when somebody runs, let's say I have a class called game and there's a score method. So when somebody does run a score method, then go ahead and run this method, which I can in turn run the original code of the SCORE method, but I can sprinkle on a little bit of logging or any of the stuff we talked about earlier. So, again,
Scott Tolinski
Deckorators, they're written as just a straight up normal function again, given the parameters that we mentioned.
Defining decorators as normal functions
Scott Tolinski
But when you wanna use them, you just use them using the at sign like we said already with the decorator's name and you place this on top or sometimes next to to to the left of. I wanna say instead of next to. The left of the thing you're trying to decorate. So for instance, if you're decorating a class at decorator name and then immediately following that the class definition.
Scott Tolinski
But if you're doing it on a field inside of a class, you do add decorator name space Then the variable name and then its definition equals to number 1. Whatever.
Syntax for decorating classes vs properties
Scott Tolinski
So it's a little interesting. It seems like if it's On a, on a function or method, you're always defining it above it. But on an individual field, it's defined next to it. I wonder why that's different.
Scott Tolinski
Kinda feels like they should always be on top. Right? Is is that, like, a syntax thing, or is that just people like to format it that specifically that's that way? I've seen I've only seen it this way in the examples, so I would be inclined to say it's a syntax thing.
Syntax likely required, not just convention
Wes Bos
Yeah. I I think you're right as well. I've only ever seen it that way.
Wes Bos
I guess it makes sense because generally your, properties are are only a one liners. Right? You wanna you wanna set a piece of state on your class. And if you wanna tag that as reactive, just at reactive in front of it. Yeah. Have you seen this auto accessor stuff as well?
Scott Tolinski
No. What is that? Okay. So a part of this proposal is this auto accessor.
Auto accessors syntactic sugar for private variables
Scott Tolinski
And an auto accessor is a syntax a word the a keyword named accessor.
Scott Tolinski
So if you were to say I have a class.
Scott Tolinski
Yep. And inside of my class Is what should be a private property.
Scott Tolinski
What you do with this API is you write accessor, the name of the value, and then you assign it. And what what it is, it's a shorthand for first creating a private variable, also creating a get method, and creating a set method for. So this thing is syntactical sugar for creating a private variable with a getter and a setter. Now the reason this is relates 2 decorators is that if you decorate in an auto accessor, if you decorate an auto accessor, it gives you more things. Okay. What it does is it gives you the ability to return a custom, get a custom set and a custom init function All from within the decorator that you don't get unless it's an auto accessor.
Benefits of auto accessors with decorators
Wes Bos
Oh, I see.
Wes Bos
If you have a private property on a class. You put the little pound in front of it.
Wes Bos
And then if you want to be able to get and set those, you have to create your own getters and setter values and do all the logic inside of that. And often it's simply just returning the private value and setting the private value.
Wes Bos
So adding an accessor will
Scott Tolinski
do all 3 of those things for you in one go? It it does all 3 of those things for you in one go in addition to giving your decorator more functionality.
Wes Bos
Oh, okay.
Example of auto accessor decorator
Scott Tolinski
Oh, that's pretty cool. Yeah. It it is interesting. And it seems like An example that I've seen is specifically like a reactive variable where you do reactive accessor my value.
Scott Tolinski
And then that would create essentially a reactive private my value, and you get access to initializing it, getting in, setting it all within the decorator.
Wes Bos
And the the benefit of that is that, Like getting and setting the value to you, the user, is simply just saying my game dot score equals 6 Or console log my game dot score. Those are getters and setters. Right? And to you, you're just setting a property. Right? But what's actually happening under the hood is there's a get function is running and returning the private value, but there might be other things that are happening.
Wes Bos
Updating it. You might be logging it. There's a lot that could really happen. And like I said, to you, the user, you're just accessing a value or you're just setting a value, but There could be a lot more logic under the hood that's going on, and this is just a bit of a shortcut to that. Yeah. Pretty neat stuff. Again,
Benefits of getters/setters to end user
Scott Tolinski
As a primarily functional programmer, you know, it's not stuff that I feel like I hit all the time. But I do think Mhmm. That this is fascinating and something that, You know, makes me want to explore classes a little bit more given how powerful they can be. Yeah, absolutely. I think
Wes Bos
maybe it's time we write a couple what, lit web component applications?
Plan to explore classes more due to decorator power
Scott Tolinski
Maybe a full on Angular dev? Yeah, which one though? Angular or Angular JS? Which one?
Wes Bos
Which one is the 1? In researching this episode, I Googled some like decorator for Angular.
Wes Bos
Yeah. And
Scott Tolinski
The old docs came up and it's just like, oh, like, is this still a thing where There are yes. It's still a thing and people correct you if you say the wrong one. So what are we supposed to say? Oh, let me tell you. Here's what we're supposed to say. Anytime I have to know the difference, I Google them both and compare them, And then I come up with the answer. That's what I do. If if I get an implant in my brain, at some point It's angular. Before I die, It's going to be just a function that returns the correct version of Angular based on what we're talking about.
Scott Tolinski
I have no clue. That's like,
Wes Bos
WordPress has a function. It's called it's capital P, dang it. So if you type WordPress incorrectly, like like without a capital p in it, it will AutoCorrect it to capital P. So it's a nice little function that fixes it. So AngularJS is the old one. It's been deprecated for almost 2 years now.
AngularJS vs Angular version clarification
Wes Bos
Angular is the new one.
Wes Bos
Not the new one, the one that's been around for forever. I'm just gonna say Angular JS folks,
Scott Tolinski
just upgrade it and drop drop the JS. It's cleaner. That's that's what they it. No. I'm saying that the if you're still using the the old one, not not the Angular devs, not the people who work on Angular. I wonder how much Angular JS is still use. Let's find let's go to npm. Do people npm install AngularJS? I bet it's I bet it's astounding. I bet it is used By a 1000000000 people.
Wes Bos
When I use Angular JS, I just put it use a script tag. Right? Like, I didn't npm install anything. Yeah. I definitely did that as well. Npm install Angular JS is some random package for Browserify.
Wes Bos
Oh.
npm installs for AngularJS vs Angular packages
Wes Bos
Oh, here we go.
Wes Bos
Npm install Angular is the legacy Angular JS. Oh, no.
Wes Bos
Bro.
Wes Bos
So nvm installing Angular is Angular JS.
Wes Bos
So if you want if you want Angular, The new version you have to at import. So there's 500,000 weekly downloads of Angular JS.
Wes Bos
Let's see what
Scott Tolinski
what the other one is. And three point 2,000,000 downloads of Angular Core.
Many old AngularJS apps not using npm
Wes Bos
So it's and like and how much how many AngularJS apps are not using npm. I bet a lot because when I bet a lot. A lot of those apps were built, no we weren't using build systems. We're just Script tag, PHP, and, just like you were just writing Angular, like loops and stuff right in your HTML that was the whole
Scott Tolinski
the benefit of it. Yeah. In fact, I have an Angular app That's online still. I just checked it. It's just loading it off of the script. So Is it Angular or Angular JS, Scott? It's it's it was it is Angular JS, but it's before there was a difference.
Scott Tolinski
Oh, my God. I can tell you exactly what version it is.
Wes Bos
It's version 1.2. It's a good one. That's a good one. When when did that come out? I could not tell you.
Scott Tolinski
It does say it was using Angular route.
Scott Tolinski
Oh, and yeah. The copyright is 2014,
Wes Bos
so 1.2 came out 10 years ago. Wow. Yeah.
AngularJS 1.2 released 10 years ago
Wes Bos
It feels like it was sooner ago. We should have somebody on to talk about
Scott Tolinski
Angular. Yeah. Doesn't Sarah Drysner work on Angular now? I don't know. Maybe.
Wes Bos
Every now and then we get people being like, I wish you would talk more about Angular. And same with Vue.
Wes Bos
And we don't talk about them, not because we don't like them, because we don't use them. So maybe we'll have some folk on if you know somebody, the king of Angular tweet us because we're the queen of Angular. Oh, yeah. The queen of and literally anybody who is royalty in the Angular family.
Wes Bos
Yes.
Wes Bos
Alright. Anything else to add about decorators?
Scott Tolinski
Oh, no. I don't. I don't have anything to add About decorators. But, you know, I think they're interesting. I'm glad to see that they're finally approaching, hopefully, a place where they're actually being added to the browser. Beautiful. Alright. Thanks, Larry, for tuning in. Catch you later.
Wes Bos
Peace.
Scott Tolinski
Head on over to syntax.fm for a full archive of all of our shows.
Scott Tolinski
And don't forget to subscribe in your podcast player or drop a review if you like this show.