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());
@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