Links
- Inheritance revisited | MDN
- Basically, if you understood how inheritance worked
in terms of
__proto__
, you were good but it turns out that__proto__
was never in the standard.__proto__
is internally referred to as[[Prototype]]
and it seemed that, pre-ES6 (which is standardizing it), the only way to read the property was viaObject.getPrototypeOf()
(or hope thatobj.constructor.prototype
is correct) and the only way to set it was once during construction via thenew()
operator. Though__proto__
has been standardized for ES6, setting it is a big no-no for performance. Ref:__proto__
- You can use
__proto__
in object literal notation to set the prototype instead of usingObject.create()
.
- Basically, if you understood how inheritance worked
in terms of
- ECMAScript 5 Objects and Properties (John Resig, 2009)
- The pitfalls of using objects as maps
- Working with objects
- Enumerability and ownership of properties
- delete operator
- Object.keys(o)
- Object.getOwnPropertyNames(o)
- Object.defineProperty
- Object.defineProperties()
- Object.propertyIsEnumerable()
- Object.getOwnPropertyDescriptor()
- object.watch()
- object.unwatch()
- get
- set
- Object.create()
- extensible objects: isExtensible
- Inheritance
- Inheritance and the prototype chain
- Inheritance and the constructor's prototype
- Inheritance revisited - JavaScript | MDN
- instanceof operator
object.__proto__
- See also: http://stackoverflow.com/a/7156682
- Object.isPrototypeOf
- Object.getPrototypeOf
- Object.create
- JavaScript inheritance by example
- What’s up with the “constructor” property in JavaScript?
- JavaScript properties: inheritance and enumerability
- A closer look at super-references (ES6)
3 ways of inheritance
Google Closure: goog.inherits
Ref: http://docs.closure-library.googlecode.com/git/closure_goog_base.js.source.html
/** * Inherit the prototype methods from one constructor into another. * * Usage: * <pre> * function ParentClass(a, b) { } * ParentClass.prototype.foo = function(a) { } * * function ChildClass(a, b, c) { * goog.base(this, a, b); * } * goog.inherits(ChildClass, ParentClass); * * var child = new ChildClass('a', 'b', 'see'); * child.foo(); // works * </pre> * * In addition, a superclass' implementation of a method can be invoked * as follows: * * <pre> * ChildClass.prototype.foo = function(a) { * ChildClass.superClass_.foo.call(this, a); * // other code * }; * </pre> * * @param {Function} childCtor Child class. * @param {Function} parentCtor Parent class. */ goog.inherits = function(childCtor, parentCtor) { /** @constructor */ function tempCtor() {}; tempCtor.prototype = parentCtor.prototype; childCtor.superClass_ = parentCtor.prototype; // DIFF childCtor.prototype = new tempCtor(); /** @override */ childCtor.prototype.constructor = childCtor; };
TypeScript: __extends
function __extends(childCtor, parentCtor) { for (var key in parentCtor) { if (parentCtor.hasOwnProperty(key)) { childCtor[key] = parentCtor[key]; } } function tempCtor() { this.constructor = childCtor; } tempCtor.prototype = parentCtor.prototype; childCtor.prototype = new tempCtor(); };
Coffeescript: __extends
function __extends(childCtor, parentCtor) { for (var key in parentCtor) { if (parentCtor.hasOwnProperty(key)) { childCtor[key] = parentCtor[key]; } } function tempCtor() { this.constructor = childCtor; } tempCtor.prototype = parentCtor.prototype; childCtor.prototype = new tempCtor(); childCtor.__super__ = parentCtor.prototype; // DIFF return childCtor; }; var Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return console.log(this.name + (" moved " + meters + "m.")); }; return Animal; })(); var Snake = (function(_super) { __extends(Snake, _super); function Snake() { _ref = Snake.__super__.constructor.apply(this, arguments); return _ref; } Snake.prototype.move = function() { console.log("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake; })(Animal); var sam = new Snake("Sammy the Python"); sam.move();
Chirayu – prototype chain
Mutating __proto__
is a big big no-no for performance! Ref __proto__
under IE.
Ref: http://codepen.io/chirayuk/pen/lCkHx
function Animal(name) { this.name = name; }; Animal.prototype.move = function(meters) { return console.log(this.name + (" moved " + meters + "m.")); }; // Snake extends Animal function Snake(name) { Animal.apply(this, arguments); // Snake.__super__.apply(this, arguments); }; Snake.prototype = { __proto__: Animal.prototype, move: function() { console.log("Slithering..."); Animal.prototype.move.call(this, 5); // Snake.__super__.prototype.move.call(this, 5); } }; // Snake.__super__ = Animal; var sammy = new Snake("Sammy the Python"); sammy.move();
Node.js – utils.inherits
exports.inherits = function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); };
Misc
function foo() {} foo.prototype.__proto__ === Object.prototype ; // true