DEV Community

Cover image for Classes in JavaScript
Samantha Ming
Samantha Ming

Posted on • Edited on • Originally published at samanthaming.com

Classes in JavaScript

Alt Text

When I say ES6 Classes, you might go YAY 🎊 JS finally introduced a new object-oriented inheritance model. Well, not exactly. It’s still using the existing prototype-based inheritance (labeled as β€œOld” in the photo). But now it just looks more like Object Oriented Programming (OOP). Yay, I think this syntactical sugar is GREAT!

// Old way

var Meal = function(food) {
  this.food = food;
};

Meal.prototype.eat = function() {
  return 'πŸ˜‹';
};

// Classes in ES6

class Meal {
  constructor(food) {
    this.food = food;
  }

  eat() {
    return 'πŸ˜‹';
  }
}

Defining a Class

For those coming from Object-Oriented Programming, then you're good. But for those new to this or just want a friendly reminder. The first step is to create our class. The keyword to use is class.

class Meal {
  constructor(food) {
    this.food = food;
  }

  // Prototype Method
  eat() {
    return 'πŸ˜‹';
  }

  // Static Method
  static utensil() {
    return 'πŸ₯’';
  }
}

Constructor: This is a special method for initializing an instance of that class. So what that means is that whenever we create a new instance of the class, it will invoke the constructor. This is a great place to set some properties and assign parameters. For our example, we want to make sure when someone creates a new Meal instance, they have a costume in place.

Prototype Method: A prototype method is a method that is only accessible when you create an instance of the class. This will be clear when I show you an example later.

Static Method: A static method is something you can call without instantiating the class. More on this later.

Create a Class Instance

Great, now you created the class. Let's create an instance of it using the new keyword.

class Meal { ... }

const dumpling = new Meal('πŸ₯Ÿ');

Now we can call our prototype method:

dumpling.eat();
// 'πŸ₯Ÿ'

⚠️ But! you can't access static methods.

dumpling.utensil();
// TypeError

That's because static methods are not accessible by the instance. It can only be called by the class

Meal.utensil();
// 'πŸ₯’'

Static vs Instance Methods

So you must be wondering when you should use a static or instance methods. Here's a very simple answer. Use static methods when you don't want to create an instance of the class. Lol, I know that's not a very satisfactory answer. Most of the time, you will see static methods used for creating utility functions for an application. Any other time, it's better to stick with an instance method.

No Arrow Function

Another cool thing ES6 introduced is Arrow Function

MDN: An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.

Arrow Function has No Prototype Property

So in the non-sugar way, notice we used the function keyword:

var Meal = function(food) {
  this.food = food;
};

Meal.prototype.eat = function() {
  // <-- No Arrow Function
  return 'πŸ˜‹';
};

The arrow function does not have a prototype property, so we can not use the arrow function.

// ❌
Meal.prototype.eat = () => 'πŸ˜‹';
Meal.prototype; // undefined

Arrow Function has No New Operator

Second thing, arrow functions can't be used as constructors.

// ❌
const Meal = () => {}

const rawChicken = new Meal()
// TypeError: Meal is not a constructor

So here's another one where you should use the regular function syntax.

// βœ…
const Meal = function(){}

const cookedChicken = new Meal()

Sugar is bad for you!

Some of you may argue that class is bad because it obscures the true nature of JS. And I think that is absolutely a fair point. Let's peel back at the intention of classes. It was introduced to make JavaScript easier to pick up πŸ‘

For those coming from an object-oriented programming language such as Ruby or Python, this will make the transition of learning JS a lot easier because of the familiar syntax. For newcomers, this will mean it's faster to ramped up and ready to go. And once you get going, hopefully, you will be encouraged to dive deeper into the JS and learn what's actually under the hood πŸ€“

But a spoonful of sugar makes the medicine go down...🎢

Learning a new language is hard, so if we can make this process a bit easier, I think that's a great thing. It's very easy to be overwhelmed when everything is thrown at you. It's like trying to drink from a fire hose, you end up drinking no water at all. That's why tutorials are done by steps. No one goes from a white belt to a black belt right away. You have to go through the process, it requires time.

So should you employ class? -- well that depends on you and your team. Like I always say, there is never a right way; the right way is always it depends πŸ˜‰ Let's not immediately dismiss "sugar" as bad. As developers, we should always keep an open mind to new ideas. Less judgment, more listening, and assume good intentions 😊

Community Input

Please note when you use the typeof on a class, it will return function.

class someClass {}

typeof someClass; // 'function'

Thanks @ianwijma

Resources


Thanks for reading ❀
To find more code tidbits, please visit samanthaming.com

🎨Instagram 🌟Twitter πŸ‘©πŸ»β€πŸ’»SamanthaMing.com

Top comments (21)

Collapse
 
vasilicaolariu profile image
Vasilica Olariu

The example given for Arrow Function has No Prototype Property isn't correct.

The problem with arrow functions (actually one of it's feature) is it always has the same this, as a result you can't use it as a method because this will always be the this from the context you defined the function (eg. window).

You're pointing out that Meal.prototype will be undefined after defining .eat as an arrow function. that's not correct.

Here's an example that explains the problem:
i.imgur.com/NwDHYYr.png

As you can see, the arrow function doesn't know about this.food.

Collapse
 
blackr1234 profile image
blackr1234

Great and useful article!

For me, I very seldom use JS classes. When I write React JS, I write function components instead of class components.

One minor typo thing: I think when you write cont they should be const under the section "Arrow Function has No New Operator".

Collapse
 
samanthaming profile image
Samantha Ming

Oh great catch! thanks for letting me know, i'll fix it πŸ‘

Collapse
 
genericallyloud profile image
Russell Leggett

I was somewhat involved during the design of classes for JavaScript and I can tell you - it was really touch and go there whether classes were going to be added, and if so, how they would be added. Most people involved wanted classes, but nobody could really agree what they should be. Some people wanted classes to be entirely different and an alternative to prototypes. The failed ES4 that never came to fruition was pursuing that approach. Ultimately the simple sugar approach won the day in the Maximally Minimal class proposal.

At the time, there were a lot of ad hoc and incompatible libraries that simulated classes. Additionally, there are aspects of the class pattern that were extremely error prone to do by hand - things like inheritance and doing super calls especially which were fixed with the new class syntax. Technically, the way super works is not possible to do with the old prototype style. It also dovetailed well into Microsoft's desire to create TypeScript and wanting to create something familiar to C# devs. While functional programming was definitely a big influence at the time, it didn't have the same hold that it has now. It's interesting to consider whether or not it was a good choice since many people are moving away from really using prototypes at all and trying to stick to pure functional style now, but the landscape was very different at the time.

Collapse
 
ianwijma profile image
Ian Wijma

One thing I personally don't like about classes in JS is that they are PURE syntactic sugar over functions. If you do typeof on a class it returns function. Which imo should return class. But that might just be me.

Collapse
 
samanthaming profile image
Samantha Ming

woo good point! that might throw some people off -- let me add that to my notes, thanks for sharing!

Collapse
 
dzienisz profile image
Kamil Dzieniszewski

I think we are lack of good plugins that will explain all of those quirks to new users or there are any?

Collapse
 
drubb profile image
drubb

Thanks for this useful introduction. As a PHP developer I've always wondered why so many JS people argue against using classes, e.g. in frameworks like React or VueJS. As for me, classes are still very useful, and their real power comes with inheritance / extensions.

Collapse
 
aminmansuri profile image
hidden_dude

Javascript was originally (and probably still is) an OO language based on prototypes instead of classes. This first appeared in Self and is a somewhat elegant way of doing OO. At least in theory.

Of course, real OO always could do anonymous functions/blocks/closures.. but the half-backed "popular" languages of the late 80s and 90s often omitted these features that were there at the inception of OO.

Javascript isn't the most complete language but in its elegant simplicity it included a lot of the original OO feel even though it chose to go with prototypes instead of classes.

Many today are discovering the functional programming techniques Smalltalkers used daily.

Collapse
 
speshov profile image
SPeshov

Great article! In my judgment, we can achieve the same results and cleaner code with functional programming. I personally avoid using them πŸ€·β€β™‚οΈ

Collapse
 
samanthaming profile image
Samantha Ming

Fair! And that's great! you got to do what works best for you 😊 -- My first language was Ruby, so I do lean towards class, for familiarity πŸ˜… But you know what, I'm going to challenge myself to write some code tidbit on the function way if I can demystify it, I think that will super cool πŸ₯³ -- will add that to my list πŸ’ͺ

Collapse
 
gregfletcher profile image
Greg Fletcher

Great article!

I don't use classes that much but they're really useful in some cases. Great that we've got the choice now.

It's interesting that projects like TypeScript are written purely in a functional style. I found that ironic because TypeScript initially introduced classes as a possible syntax. Now it's part of the JS spec but TypeScript is written in a functional style. Anders Hejlsberg (C# and TypeScript creator) talks about it a lot in his talks. Nothing wrong with classes. Just interesting to see functions become accepted more and more in programming.

Programming styles interest me so I'm purely an observer. Not advocating for one over the other.

Collapse
 
haidv profile image
HaiDV

But actually, after being transpiling by Babel, it turns out that class is transpilered to prototype

Collapse
 
5456qwe profile image
1214586

I absolutely prefer functional programming. Thanks.

Collapse
 
samanthaming profile image
Samantha Ming

Fair! You got to do what works best for you! πŸ‘