Refactor Inheritance with JavaScript Classes to Object Composition with Factory Functions

Thomas Greco
InstructorThomas Greco
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 5 years ago

The ES6 class keyword is just a neat syntax for creating constructor functions in JavaScript. The issue is that constructors force us to write tightly coupled code. In this lesson, we check out the use of factory functions and how they can be used to solve the issues that constructor's bring about.

Instructor: [00:01] On this page, I'm going to define a new function using the ES6 class keyword. Our player class is going to take an object that has a name. I'm going to set the default value to default name. We are also going to give it a default health property with a value of 100.

[00:25] Inside of our constructor, we're going to use the this keyword to give us access to the new names and healths that are going to be passed into this class. If nothing's passed in, it's going to create an object with these default values.

[00:41] The last thing I'm going to give the player class is a method called reportStatus. When this method is called, it's going to log out a statement that says the player's name, along with his health percentage value.

[00:54] Now that my class is defined, I'm going to go ahead and instantiate an object from it. Here, I'm making a player1 variable. Since our class is essentially a constructor function, we're going to need to use the new keyword to instantiate new objects.

[01:12] Here, I'm going to create a new player with the name of John Smith. I'm going to leave the health alone, so we get the default health back.

[01:24] Now, if we log this out and execute this file, we'll see that an object has been created for us, and it has the name John Smith, as well as the default health of 100. Additionally, we can hook into our constant and fire off that reportStatus method as well.

[01:40] Let's see how we could do this with the factory function. A factory function is simply a function that takes in objects and it turns them. In this case, our factory function is going to take in an object that has a name and a health property.

[01:59] Just like in our class, I'm assigning default values to the name and health properties. Then all we need to do is pass them into the object we're returning. I also want to pass in that reportStatus function that we defined as a method in player.

[02:15] Now that our factory is complete, we can use it to create a player2 variable. Once again, I'm just changing the name from default name to Mike Tyson. We're going to keep the default health.

[02:29] Now, if we log this out, we should see an object being created, with the name Mike Tyson and a health of 100. If we run that report status, we'll see that that works as well.

[02:41] It's important to note that when using factories, as opposed to constructors, we don't have to use the new keyword, and therefore, we don't have to worry about forgetting to use the new keyword when creating an object.

[02:53] Additionally, factory functions give the standard usage of the this keyword. As a result, we're able to create new objects without having to tinker with this.

Luis
Luis
~ 6 years ago

In both examples you're returning the 'console.log' which is returning undefined as is printed in the console.

Thomas Greco
Thomas Grecoinstructor
~ 6 years ago

hey luis I appreciate you're observation :) the standard behavior of console.log is that it will return undefined so even though we're using it to take a look at our values, we're still going to see undefined in the console.

Adallo
Adallo
~ 6 years ago

Hey, the main diference her is, that class syntax, the method lives in class prototype, but in your factory function is a property, so it's assigned for every single player object..

Vlad
Vlad
~ 6 years ago

This is kinda bad. You should point out that 1000 persons created with the class (prototype syntax sugar) will only create the reportStatus function once in memory and share it between all objects while the second approach will duplicate the same function code over and over again.

Thomas Greco
Thomas Grecoinstructor
~ 6 years ago

Hey! More astute observations. When using the class keyword (constructor syntax sugar) there is the possibility for a slight performance benefit however it is so minor that unless you need to create tens of thousands objects, then you should prefer factory functions. That being said, this video isn’t intended to teach you about the unavoidable issues that arise when class-based inheritance is used in JavaScript. Instead, the goal is to open viewers eyes to the fact that anything created with class can be replicated within a factory function.

Vlad
Vlad
~ 6 years ago

Agreed Tom, performance wise we won't see differences. Functionality wise they will behave differently. Changing the function on the prototype will change the way all instances work at runtime. This is way it feels a bit wrong. From your explanation it seemed that there is no functionality loss, only gains by using the factory function.

Thomas Greco
Thomas Grecoinstructor
~ 6 years ago

There is no functionality lost when choosing factories over classes. On the contrary, constructors can make software developers lives much more frustrating than a regular ol' factory function!

I should clarify refactoring classes to factory functions is going to break all of the objects previously created with that class. In addition to modifying the behavior of the this keyword, constructors created objects with the new keyword therefore all callers of that constructor are going to be impacted.

Markdown supported.
Become a member to join the discussionEnroll Today