
17/11/2024
JavaScript is known for its unique approach to inheritance, which is quite different from classical inheritance found in languages like Java or C++. Instead of using classes and instances, JavaScript relies on prototypes, creating a chain of objects that can inherit properties and methods. Let’s break down how prototypal inheritance works in JavaScript.
Every JavaScript object has an internal property called [[Prototype]] (often accessible via __proto__ or Object.getPrototypeOf()). This prototype property points to another object, which acts as a template. If you try to access a property that doesn't exist on an object, JavaScript will look up the prototype chain to find it.
const animal = { sound: 'generic sound', speak: function() { console.log(this.sound); } }; const dog = Object.create(animal); dog.sound = 'bark'; dog.speak(); // Output: 'bark'
In this example, dog inherits from animal. If dog didn’t have the speak method or the sound property, JavaScript would look up the prototype chain to the animal object.
You can create a new object using Object.create(), which allows you to set the prototype of the newly created object to an existing one. This method is a direct way to establish a prototype relationship.
const cat = Object.create(animal); cat.sound = 'meow'; cat.speak(); // Output: 'meow'
Here, cat inherits the speak method from animal and sets its own sound property.
The prototype chain is crucial for understanding how JavaScript looks for properties and methods. If an object does not have a property, JavaScript checks its prototype, and if that prototype doesn’t have it either, it continues up the chain. This continues until it reaches null, which signifies the end of the chain.
console.log(dog.hasOwnProperty('sound')); // Output: true console.log(dog.hasOwnProperty('speak')); // Output: false console.log(Object.getPrototypeOf(dog) === animal); // Output: true
In this case, dog has its own sound property but inherits speak from animal.
You can modify the prototype of an object even after it has been created, affecting all objects that inherit from that prototype. This can be a powerful feature but should be used with caution.
animal.walk = function() { console.log('Animal walking'); }; dog.walk(); // Output: 'Animal walking'
Now, both dog and any other object inheriting from animal have access to the walk method.
JavaScript also employs constructor functions for creating multiple objects that share the same prototype. When using a constructor, you define a function and then create instances using the new keyword.
function Animal(sound) { this.sound = sound; } Animal.prototype.speak = function() { console.log(this.sound); }; const bird = new Animal('chirp'); bird.speak(); // Output: 'chirp'
In this case, Animal.prototype serves as the prototype from which all instances created with new Animal() can inherit the speak method.
With ES6, JavaScript introduced class syntax, which provides a cleaner way to work with constructor functions and prototypal inheritance. Although it looks similar to classical inheritance, under the hood, it is still using prototypal inheritance.
class Animal { constructor(sound) { this.sound = sound; } speak() { console.log(this.sound); } } const fish = new Animal('blub'); fish.speak(); // Output: 'blub'
Here, the speak method is defined in the prototype of the class Animal.
Understanding prototypal inheritance provides a strong foundation for working with JavaScript. By leveraging prototypes, you can create efficient and reusable code patterns that enhance your development capabilities.
18/11/2024 | VanillaJS
29/10/2024 | VanillaJS
17/11/2024 | VanillaJS
17/11/2024 | VanillaJS
29/10/2024 | VanillaJS
17/11/2024 | VanillaJS
17/11/2024 | VanillaJS