Last active
June 28, 2017 06:58
-
-
Save philipstanislaus/bad92373edee1d45887f06ce6fa260eb to your computer and use it in GitHub Desktop.
JavaScript inheritance (prototype, __proto__, constructor) in ES2015/ES6 and ES5
This file contains 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
class Animal { | |
animalProp() {} | |
} | |
// ES2015/ES6 | |
class Cat extends Animal { | |
catProp() {} | |
} | |
const myCat = new Cat() | |
// ES5 | |
function OldCat() {} | |
OldCat.prototype = Object.create(Animal.prototype) | |
OldCat.prototype.constructor = OldCat | |
const myOldCat = new OldCat() | |
////////// | |
// Gotchas (all the code examples evaluate to true) | |
// | |
// 1. An ES2015/ES6 `class` like Cat/Animal is a constructor function, not an object. | |
typeof Animal === 'function' | |
typeof Cat === 'function' | |
// | |
// 2. `__proto__` is the way up the prototype chain. It is used for lookups. It exists on all objects. | |
Cat.__proto__ === Animal | |
Cat.prototype.__proto__ === Animal.prototype | |
// | |
// 3. There are 2 inheritance chains: one for constructors, and one for prototypes. Navigation between them is possible: | |
// __proto__ always points up the chain, `prototype` points from the constructor chain to the prototype chain, and | |
// `constructor` points from the prototype chain to the constructor chain: | |
// | |
// Constructor Prototype | |
// =========== ========= | |
// | |
// Object.prototype | |
// | |
// Function.prototype | |
// | |
// Animal --> .prototype Animal.prototype | |
// <-- .constructor | |
// | |
// Cat --> .prototype Cat.prototype | |
// <-- .constructor | |
// | |
// myCat | |
// | |
// | |
// 4. `prototype` will be used by the constructor function as the prototype of the newly created object. It is the | |
// blueprint for objects that will be created from the constructor. Since all functions can be used as constructor | |
// functions, the prototype property exists on all functions (and also on classes, since they are syntactic sugar for | |
// constructor functions). | |
Cat.prototype === myCat.__proto__ | |
(function () {}).hasOwnProperty('prototype') === true | |
// | |
// 5. `constructor` exists on every prototype, and refers back to the constructor of that prototype. Like any other property, the `constructor` property can be accessed from any child object, and points to the constructor function of its prototype. | |
myCat.hasOwnProperty('constructor') === false | |
myCat.__proto__.hasOwnProperty('constructor') === true | |
myCat.__proto__.constructor === Cat | |
myCat.constructor === Cat | |
// For a map, see: https://stackoverflow.com/a/11249437/6694848 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment