Last active
October 21, 2023 03:31
-
-
Save jabed-web-dev/82419d1c1e0ee6359feb0ae9aaf33191 to your computer and use it in GitHub Desktop.
Understanding Prototypes and Inheritance in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| // Initialize constructor functions Constructor/Prototype | |
| function Person(firstName, lastName) { | |
| this.firstName = firstName | |
| this.lastName = lastName | |
| } | |
| Person.prototype.getFullName = function () { | |
| return this.firstName + ' ' + this.lastName | |
| } | |
| let p1 = new Person('John', 'Doe') | |
| let p2 = new Person('Jane', 'Doe') | |
| // Whether p1 is created from the Person object | |
| console.log(p1 instanceof Person) | |
| console.log(p1.getFullName()) | |
| console.log(p2.getFullName()) | |
| } | |
| { | |
| // Add a check at the beginning of the Car() function | |
| function Car(brand) { | |
| if (!(this instanceof Car)) { | |
| throw Error('Must use the new operator to call the function') | |
| } | |
| this.brand = brand | |
| } | |
| } | |
| { | |
| // Prototypal Inheritance | |
| function Hero(name, level) { | |
| this.name = name | |
| this.level = level | |
| } | |
| function Warrior(name, level, weapon) { | |
| Hero.call(this, name, level) | |
| this.weapon = weapon | |
| } | |
| function Healer(name, level, spell) { | |
| Hero.call(this, name, level) | |
| this.spell = spell | |
| } | |
| // Link prototypes and add prototype methods | |
| Object.setPrototypeOf(Warrior.prototype, Hero.prototype) | |
| Object.setPrototypeOf(Healer.prototype, Hero.prototype) | |
| Hero.prototype.greet = function () { | |
| return `${this.name} says hello.` | |
| } | |
| Warrior.prototype.attack = function () { | |
| return `${this.name} attacks with the ${this.weapon}.` | |
| } | |
| Healer.prototype.heal = function () { | |
| return `${this.name} casts ${this.spell}.` | |
| } | |
| // Initialize individual character instances | |
| const hero1 = new Warrior('Bjorn', 1, 'axe') | |
| const hero2 = new Healer('Kanin', 1, 'cure') | |
| } | |
| { | |
| // prototypal inheritance and __proto__ | |
| // never use the __proto__ property in the production code. | |
| const parent = { | |
| value: 2, | |
| method() { | |
| return this.value * 2 | |
| }, | |
| } | |
| console.log(parent.method()) // 4 | |
| const child = { | |
| value: 5, | |
| __proto__: parent, | |
| } | |
| console.log(child.method()) // 10 | |
| child.value = 4 | |
| console.log(child.Method()) // 8 | |
| // Get Object has own property | |
| for (const key in child) { | |
| if (child.hasOwnProperty(key)) { | |
| console.log(child[key]) | |
| } | |
| } | |
| } | |
| { | |
| // A standard way to implement prototypal inheritance in ES5 | |
| let person = { | |
| name: 'John Doe', | |
| greet: function () { | |
| return "Hi, I'm " + this.name | |
| }, | |
| } | |
| // let teacher = Object.create(person); // second argument optional | |
| // teacher.name = 'Jane Doe'; | |
| let teacher = Object.create(person, { | |
| name: { value: 'John Doe' }, | |
| teach: { | |
| value: function (subject) { | |
| return 'I can teach ' + subject | |
| }, | |
| }, | |
| }) | |
| console.log(Object.getPrototypeOf(teacher) === person) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment