Last active
April 24, 2024 10:05
-
-
Save muodov/37aa848391be6c094b00b175cb3f9347 to your computer and use it in GitHub Desktop.
JS prototype inheritance cheatsheet
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
// normal function x | |
function x() { | |
this.a = 1; | |
} | |
// First of all, the term "prototype" is confusing because it can refer to 2 different things. | |
// There is an object's prototype, which is another object used to look up missing properties. | |
// But there is also an actual `prototype` property on Function and class objects, which is NOT a prototype for that function object! | |
// Instead, it serves a very specific purpose: that object becomes a prototype of all instances returned when that function is used as a constructor: | |
(new x()).__proto__ === x.prototype | |
// function's `prototype` is an object. That object serves as a template for instances | |
x.prototype === { constructor: f x() } | |
// instances are objects. Missing properties are looked up in function's `prototype` | |
x.prototype.b = 2 | |
(new x()) ~ { a: 1 } | |
(new x()).b === 2 | |
// there is NO `prototype` on instances. It only makes sense on functions used as constructors, and class objects | |
(new x()).prototype === undefined | |
// original function is USUALLY accessible in instance as `constructor`. However, it is not always the case for some built-in globals. E.g. .constructor on `Audio` instances is set to `HTMLAudioElement` | |
(new x()).constructor === x | |
(new Audio()).constructor === HTMLAudioElement (!== Audio) | |
// function's `prototype` is accessible in instance as `__proto__` or as a result of Object.getPrototypeOf() | |
x.prototype === (new x()).__proto__ === Object.getPrototypeOf(new x()) | |
// so the property lookup chain for any instance is obj -> obj.__proto__ -> obj.__proto__.__proto__ -> ... | |
// or obj.constructor.prototype -> obj.constructor.prototype.__proto__ -> ... | |
// functions are objects too, so they have their own `__proto__` and `constructor` | |
x.constructor === ƒ Function() { [native code] } | |
x.constructor.prototype === x.__proto__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment