FAQ: Classes - Introduction to Classes

#1

This community-built FAQ covers the “Introduction to Classes” exercise from the lesson “Classes”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Introduction To JavaScript

FAQs on the exercise Introduction to Classes

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

#2

what is difference between factory function and creating a class for creating objects …? why to use class/factory function…?

3 Likes
#3

Where is the key ‘age’ in the object halley?

2 Likes
#4

Good question actually

#5

There is no age key in the halley object. I think they are just saying it as an example in the text

#6

Following is an article from a couple years ago that keeps it simple, but does a good job of covering all the bases. Follow up study and experimenting is up to the reader.

In Depth - JavaScript Factory Functions

This link was posted here a couple of years ago in the public interest but the article is still there and just as valid and meaningful today as it was then.

Hope it opens some doors in your mind. Don’t be afraid to bring up any other question around this topic. We do still need to extrapolate the differences between in the original question.


Continuing…

Let’s look at something simple and compare…

foo = (name, city) => {
  return {
    name,
    city
  }
};
wee = foo('Wee Gillis', 'St. William')
wee.name    // Wee Gillis
wee.city    // St. William
wee instanceof foo

Uncaught TypeError: Function has non-object prototype ‘undefined’ in instanceof check

wee instanceof Object

true

Now let’s look a class object instance…

class Foo {
  constructor (name, city) {
    name,
    city
  }
}

 > gillis = new Foo('Wee Gillis', 'St. William')
<- Foo {}

As I interpret this, it tells us that the constructor does not support destructuring. Mind, this is not an expert view, only what we observe.

class Foo {
  constructor (name, city) {
    this.name = name;
    this.city = city;
  }
}

 > gillis = new Foo('Wee Gillis', 'St. William')
<- Foo {name: "Wee Gillis", city: "St. William"}
 > gillis instanceof Foo
<- true

Clearly, if we wish to identify objects as being related to one another by their similarity and purpose object literals do not offer the same distinction as class instances. If we wish to give our object literals more functionality we have to modify the Object.prototype which is never a good idea.

If we wish to add functionality to a class, and have it reach across all instances, instantly, then we have the constructor prototype to work with and it has no bearing on the Object prototype. We’re in safe territory.

This is not necessarily an advantage in a plain sense. Our overall design and motivation is at the core of what functionality, especially dynamic functionality we will need in any one session. See it only as a difference.

 > Foo.prototype.getName = function() { return this.name }
<- ƒ () { return this.name }
 > gillis.getName()
<- "Wee Gillis"
 > Foo.prototype.getCity = function() { return this.city }
<- ƒ () { return this.city }
 > gillis.getCity()
<- "St. William"

A factory object does not have this, on the fly functionality, but what of it? If we don’t need it, then we are leaning the right way in terms of simplicity.

We may conclude that a factory object is not a class and is not a constructor. It is a plain object with only Object.prototype to inherit from. We do not invoke an instance with new, but only assignment. They are very session oriented which likely makes them easy to work with.

Remember, factory objects are similar to each other if coming from the same factory function, but they have no way of knowing their similarity since they only have Object.prototype in their inheritence chain. Everything is an object so that makes them pretty generic. Our program logic needs to draw the correlation between these objects.

Here is where a data structure comes in to help organize loosely created object instances returned from the same factory. Put them all in the same array.

 > foos = []
<- []
 > foos.push(foo('Wee Gillis', 'St. William'))
<- 1
 > foos.push(foo('MTF', 'Edmonton'))
<- 2
 > foos
<- (2) [{…}, {…}]
   0: {name: "Wee Gillis", city: "St. William"}
   1: {name: "MTF", city: "Edmonton"}
   length: 2
   __proto__: Array(0)

 > foos.map((x) => Object.values(x))
<- (2) [Array(2), Array(2)]
     0: (2) ["Wee Gillis", "St. William"]
     1: (2) ["MTF", "Edmonton"]
     length: 2
     __proto__: Array(0)
#7

Is this the explanation on what’s the difference between a Factory function and a class? it seems that the difference is that a FF just don’t use the constructor or class declaration but both do the same thing

#8

I would not so much as call it an explanation as an exploration, and patchy at best. It’s a path we can go down to explore a number of things, many of which are slightly over my head but I don’t mind being in on the conversation. Please do share your own discoveries on this topic.


Late edit, off topic

A side project would be to refactor the Build a Library project to use only factory functions. Better now, than down the road when it’s in production. It would give us a template, or sample at least of what advantages may be lost or gained, and possibly even how to mitigate any loss in functionality.

Eg.

const catalog = (media, title) => {
  return {
    _media: media,
    _title: title,
    get media() {
      return this._media;
    },
    get title() {
      return this._title;
    }
  }
}
aon = catalog('record', 'Art of Noise')
console.log(aon.media)
console.log(aon.title)

record
Art of Noise

1 Like
#9

Hi,
The getters in the first example in the explanation part (with the object Halley) don’t make sense to me.
I understand the general concept of getters, but i dont understand the logic of getting name and returning to _name.
Thank you…

#10

This is known as the backing variable, and is necessary to prevent circular references.

#11

I just noticed that there is no comma between getters and other methods within a class, unlike within an object. So I looked it up. According to MDN Classes are in fact “special functions”. So far it feels strange.

#12

Great that you noticed the difference and followed up on your hunch. Classes could almost be considered a blueprint of objects, but not a set, where an object is a compilation of attributes that is comparable to a set.

1 Like