Deep JavaScript Foundations, v3

ES6 class Keyword

Kyle Simpson

Kyle Simpson

You Don't Know JS
Deep JavaScript Foundations, v3

Check out a free preview of the full Deep JavaScript Foundations, v3 course

The "ES6 class Keyword" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle explains what a class is and outlines a few of its capabilities.


Transcript from the "ES6 class Keyword" Lesson

>> Kyle Simpson: So now we have the foundation in place. We can understand what object we're talking about when we bind to this key word. Let's look at what we can do with it. We're gonna to focus first on the class pattern since it is by far the most prevalent pattern used in JavaScript.

The class keyword is ostensibly syntactic sugar layered on top of the prototype system, which we will learn about next.
>> Kyle Simpson: So here's what it looks like. We use a class keyword, we use a name for the class keyword. By the way, this is a little know fact. Classes don't have to be statements, classes can be expressions, and they can be anonymous.

I don't ever think you should do an anonymous class expression but that is actually a thing. Classes can be defined with or without an extends clause. Here, we're just defining a class that doesn't extend anything, so it's the top level class. You can choose to define a constructor if you want, like we're doing on line 2, and you can add methods.

And look on line 4, we don't even need commas in between them. They did a fantastic job of just dribbling all kinds of syntactic sugar on this feature. It's very attractive. Then we look at line 10, it looks exactly like instantiating classes in any other class oriented language.

We just say new, capital W Workshop, and we get an instance. And we call deepJS.ask and the method call works. And there's a this context that works. So that's what the class syntax looks like. If you want to extend one class into another class, you use the extends clause like here on line 10.

You don't have to redefine any other methods that are already defined because they'll be so called inherited. So you can define new methods like the speakUp method here on line 11 and when you instantiate that Child class, you can then invoke line 18, you can invoke that method, dot speak up, exactly like it was on the object.

As a matter of fact, the class system also now has a super keyword in it, which allows you to do relative polymorphism. If you have a child class that defines a method of the same name as a parent class, so called shadowing. If you have one that defines the same method name in a child as in the parent.

You can refer to the parent from the child by saying super dot, like you see on line 12.
>> Kyle Simpson: By the way, this is an example of extension beyond syntactic sugar because prior to ES6 classes, there was essentially no way to do relative polymorphism. There was no equivalent of the super keyword.

>> Kyle Simpson: I'm not saying that's a bad thing, I'm just saying, when people say, it's just syntactic sugar anyway, no, it isn't. It's its whole own mechanism, with its own set of complexities. And if you pay attention to the specs at all, there's a whole bunch of stuff, like a big freight train headed for classes.

It's gonna explode with all kinds of new complexity, private and public fields, and private and public methods, and all these others, decorators and all this other stuff. So classes are their own complexity sync. They're gonna get all kinds of new features added into them. It's like a language within a language at this point, it's not just syntactic sugar, but that is a useful, mental model for these simplest of examples.

>> Kyle Simpson: I do have to say that even though there's a bunch of syntactic sugar, they didn't change anything fundamentally about how function calls work and how that this keyword gets bound. So, even if you define a method on a class instance, if you pass it into a said timeout, guess what?

It's gonna lose its this binding. They're not somehow magically auto bound. Those functions on class, the methods on class instances, behave just like any other function. And there are a lot of developers that were upset at that decision, they really wanted JavaScript to go one step further and force class methods to be sort of autobound the way they are in normal class or in more traditional class orientated languages.

And that idea of having an autobound this method is why in this interim period for the last several years, we have seen an explosion of patterns where people want hardbound or autobound methods and they aren't automatically. So what you see a lot happening is something like line four, where instead of defining a method on the prototype, we added into the constructor and use a hardbound method or use an arrow function, okay?

>> Kyle Simpson: This deeply troubles me to see this propagation of this idiom. This idea that it's got to be hard bound. I don't want any dynamism to it all, so I'm gonna use a lexical this from an arrow function or I'm gonna use a hard bound function to accomplish that.

Because you are essentially betraying the entire system that classes has built upon. The entire class system is built upon this idea that your methods don't exist on your instances, they exist on your prototypes and guess what happens when you say this.ask and you assign it a function? It's no longer on the prototype anymore, it's on your instance.

So every single time you instantiate a function, you're getting a whole separate copy of all those functions added to every single instance.
>> Kyle Simpson: It's not that that is particularly terrible for performance cuz JavaScript engines are actually pretty good at it. The real problem I have with that is it's exactly like we talked about in this key word.

You're going to all the trouble to do all this syntactic juggling to get yourself a class system with this key word that can be super dynamic. And guess what you just created, a really terrible version of the module. A really confusing, and ugly, and brittle version of a lexical module.

We've had lexical module pattern for 20 plus years. And we ought to just be embracing and using what was already there in the language. That's not to say there's no benefit to the class system. There are definitely benefits. If you really wanna do polymorphism and multiple levels of inheritance and super and all that.

The class system is great. It's just that the vast majority of people that are using the class system, end up completely cutting it off at its knees. Cutting it off its knees, losing all the dynamic flexibility, and getting a really terrible version of what they could have had with the module pattern.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now