49 lines
1.9 KiB
Plaintext
49 lines
1.9 KiB
Plaintext
---
|
|
title: Explain how prototypal inheritance works
|
|
---
|
|
|
|
This is an extremely common JavaScript interview question. All JavaScript objects have a `__proto__` property with the exception of objects created with `Object.create(null)`, that is a reference to another object, which is called the object's "prototype". When a property is accessed on an object and if the property is not found on that object, the JavaScript engine looks at the object's `__proto__`, and the `__proto__`'s `__proto__` and so on, until it finds the property defined on one of the `__proto__`s or until it reaches the end of the prototype chain. This behavior simulates classical inheritance, but it is really more of [delegation than inheritance](https://davidwalsh.name/javascript-objects).
|
|
|
|
## Example of Prototypal Inheritance
|
|
|
|
```js
|
|
// Parent object constructor.
|
|
function Animal(name) {
|
|
this.name = name;
|
|
}
|
|
|
|
// Add a method to the parent object's prototype.
|
|
Animal.prototype.makeSound = function () {
|
|
console.log('The ' + this.constructor.name + ' makes a sound.');
|
|
};
|
|
|
|
// Child object constructor.
|
|
function Dog(name) {
|
|
Animal.call(this, name); // Call the parent constructor.
|
|
}
|
|
|
|
// Set the child object's prototype to be a new instance of the parent object.
|
|
Dog.prototype = Object.create(Animal.prototype);
|
|
|
|
// Add a method to the child object's prototype.
|
|
Dog.prototype.bark = function () {
|
|
console.log('Woof!');
|
|
};
|
|
|
|
// Create a new instance of Dog.
|
|
const bolt = new Dog('Bolt');
|
|
|
|
// Call methods on the child object.
|
|
console.log(bolt.name); // "Bolt"
|
|
bolt.makeSound(); // "The Dog makes a sound."
|
|
bolt.bark(); // "Woof!"
|
|
```
|
|
|
|
Things to note are:
|
|
|
|
- `.makeSound` is not defined on `Dog`, so the engine goes up the prototype chain and finds `.makeSound` off the inherited `Animal`.
|
|
- We need to call `Object.create` in one of following ways for the prototype methods to be inherited:
|
|
- `Object.create(Parent.prototype)`
|
|
- `Object.create(new Parent(null))`
|
|
- `Object.create(objLiteral)`
|