Skip to content

Instantly share code, notes, and snippets.

@prof3ssorSt3v3
Last active August 18, 2024 00:52
Show Gist options
  • Save prof3ssorSt3v3/c056b8b5f379ee2767bb4e8ad90f3dac to your computer and use it in GitHub Desktop.
Save prof3ssorSt3v3/c056b8b5f379ee2767bb4e8ad90f3dac to your computer and use it in GitHub Desktop.
/**
* Creating objects with Classes
* Versus objects with prototypes
* Since JavaScript is not a Class-based language
* what is happening behind the class syntax?
*/
let PersonC = class {
constructor(nm, id) {
this.name = nm;
this.id = id;
}
getDetails() {
return `${this.name} :: ${this.id}`;
}
};
let bob = new PersonC("Bob", 123);
console.log(bob.getDetails(), bob.name);
let EmployeeC = class extends PersonC {
// EmployeeC prototype links to PersonC prototype
constructor(nm, id, salary) {
super(nm, id);
this.salary = salary;
}
employeeInfo() {
//exist on the prototype of EmployeeC
return `${this.name} :: ${this.id} :: ${this.salary}`;
}
};
let noomi = new EmployeeC("Noomi", 456, 8500000);
console.log(noomi.employeeInfo());
///////////////////////////////////////////////
let PersonP = function(nm, id) {
this.name = nm;
this.id = id;
};
PersonP.prototype.getDetails = function() {
return `${this.name} :: ${this.id}`;
};
let fred = new PersonP("Fred", 321);
console.log(fred.getDetails(), fred.name);
let EmployeeP = function(nm, id, salary) {
PersonP.call(this, nm, id);
this.salary = salary;
};
Object.setPrototypeOf(EmployeeP.prototype, PersonP.prototype); //extends NOTE: THIS LINE WAS CHANGED
EmployeeP.prototype.employeeInfo = function() {
return `${this.name} :: ${this.id} :: ${this.salary}`;
};
let mary = new EmployeeP("Mary", 654, 65000);
console.log(mary.employeeInfo());
@johnaweiss
Copy link

johnaweiss commented May 1, 2020 via email

@prof3ssorSt3v3
Copy link
Author

You should absolutely learn the new syntax (ES6, 7, 8, Next). There are great improvements to the language that have been made over the last 5 years.

However, like you said, it had rocky beginnings and confusion over syntax due to pressures to make it look like and behave like Java and other OOP languages at the start. Most famous of these is the keyword new, which outside of a class-based language doesn't really make sense.

So, there have been many attempts to improve the syntax over the years when it comes to Object creation.

If the class syntax is the one that you learn first... great. go for it. But you can't stop there.

There have been three versions of the DOM too.

Everything (almost) is backwards compatible or, at least the old versions still run for the most part.

JS is a language out in the wild. Used on nearly every website built in the last 20+ years. When you have an interpreted scripting language with that level of penetration it can be a challenge. The competition between Netscape and Microsoft laid the rocky foundation for the language and features. It wasn't really until 2009 that things started to stabilize with ES5.

What has followed since was a series of faster smaller incremental improvements to the language, combined with the giant umbrella that is HTML5.

JS development for the web is not something for the faint of heart. But I prefer to think of it as exhilarating, not depressing.

There is ALWAYS something new to learn every day.

"Hooks replace classes?" - the hooks syntax meant that you didn't have to use the class syntax for every element or extend React.Component. You go simply create functions. So that is what people did.

@johnaweiss
Copy link

johnaweiss commented May 1, 2020 via email

@OliveiraCleidson
Copy link

Thank you for your video, I'm from Brazil, I wasn't finding a content like your, my doubts were solved.

@Molikaw-Saud
Copy link

Hi thank you so much for this video it helps all it
just I have one question what that easy way to do this class or prototype?

@matiuschristov
Copy link

I interpret Classes as being a simplified version of what's going on behind the scenes using prototypes.

@zhang30jin
Copy link

zhang30jin commented Oct 2, 2022

In addition to Object.setPrototypeOf(EmployeeP.prototype, PersonP.prototype);, don't we also need to set Object.setPrototypeOf(EmployeeP, PersonP); as well?

For the corresponding classes, I found that EmployeeC.__proto__ === PersonC evaluated to true. (Is that what enables a subclass to access static methods of a super class?) But EmployeeP.__proto__ === PersonP evaluates to false.

I got here from your YouTube videos. Thank you so much for posting those videos. I am trying to learn JS rigorously in the hope that I will be able to reason about programs. I often learn a topic from your videos first, before looking up books and documentation. (Otherwise at this point I'd get quite lost chasing references.) Your YouTube channel is such a valuable resource.

@prof3ssorSt3v3
Copy link
Author

I interpret Classes as being a simplified version of what's going on behind the scenes using prototypes.

Classes are a wrapper for the prototypes in JS. It's just syntactic sugar.
Real classes use inheritance while prototypes use delegation.

@prof3ssorSt3v3
Copy link
Author

Every function has a prototype object.
The prototype property is how you get to the prototype object from the function.
function Cat( ) { }
Cat.prototype
when you add a method to the prototype...
Cat.prototype.meow = function ( ) { }
when you create an instance of an object with the constructor function...
let bob = new Cat( );
the instance gets to use methods that are inside the prototype automatically
bob.meow( );
the Cat.prototype.meow method is delegated to bob.
If you need to access the prototype object directly from the instance we can use the proto property.
bob.proto.meow
Objects do not have a "prototype" property, they have a proto
If we want our object to be connected to a parent object for extending the delegation. Then we have another constructor function and it will have its own prototype.
function Animal( ){ }
Animal.prototype
For the delegation to be extended, we need the prototype chain to be established in a way that bob can call a method, say "drink"...
bob.drink( )
JavaScript looks inside the object bob for a method called drink. If not there it looks inside of Cat.prototype. If not there we want it to look inside of Animal.prototype for the method.
Cat.prototype needs to be connected to Animal.prototype. This is defining the prototype chain.
Object.setPrototypeOf( Cat.prototype, Animal.prototype )

By default, Cat.prototype and Animal.prototype will be connected to Object.prototype. By calling the setPrototypeOf method, we are changing the default for Cat.prototype to point to Animal.prototype instead of Object.prototype.
Animal.prototype still points to Object.prototype

@arthu
Copy link

arthu commented May 21, 2023

I think we also need to add Object.setPrototypeOf(EmployeeP, PersonP) to address static class method prototype inheritance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment