[JS] Add examples of prototypal inheritance (#202)

This commit is contained in:
Rob Levin 2019-06-07 00:11:11 -07:00 committed by Yangshun Tay
parent f94b90ed19
commit 8fe7aeb618
1 changed files with 74 additions and 0 deletions

View File

@ -99,10 +99,84 @@ ES6 allows you to use [arrow functions](http://2ality.com/2017/12/alternate-this
This is an extremely common JavaScript interview question. All JavaScript objects have a `prototype` property, that is a reference to another object. 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 `prototype`, and the `prototype`'s `prototype` and so on, until it finds the property defined on one of the `prototype`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
We already have a build-in `Object.create`, but if you were to provide a polyfill for it, that might look like:
```javascript
if (typeof Object.create !== 'function') {
Object.create = function (parent) {
function Tmp() {}
Tmp.prototype = parent;
return new Tmp();
};
}
const Parent = function() {
this.name = "Parent";
}
Parent.prototype.greet = function() { console.log("hello from Parent"); }
const child = Object.create(Parent.prototype);
child.cry = function() {
console.log("waaaaaahhhh!");
}
child.cry();
// Outputs: waaaaaahhhh!
child.greet();
// Outputs: hello from Parent
```
Things to note are:
* `.greet` is not defined on the _child_, so the engine goes up the prototype chain and finds `.greet` off the inherited from _Parent_.
* 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);
* Currently, `child.constructor` is pointing to the `Parent`:
```javascript
child.constructor
ƒ () {
this.name = "Parent";
}
child.constructor.name
"Parent"
```
* If we'd like to correct this, one option would be to do:
```javascript
function Child() {
Parent.call(this);
this.name = 'child';
}
Child.prototype = Parent.prototype;
Child.prototype.constructor = Child;
const c = new Child();
c.cry();
// Outputs: waaaaaahhhh!
c.greet();
// Outputs: hello from Parent
c.constructor.name;
// Outputs: "Child"
```
###### References
* https://www.quora.com/What-is-prototypal-inheritance/answer/Kyle-Simpson
* https://davidwalsh.name/javascript-objects
* https://crockford.com/javascript/prototypal.html
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
[[↑] Back to top](#js-questions)