[JS] Add examples of prototypal inheritance (#202)
This commit is contained in:
parent
f94b90ed19
commit
8fe7aeb618
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue