- Published on
Object-Oriented - Inheritance
- Authors

- Name
- 乘方
Terminology
prototype: a property on functions. It is used to share methods across instances.__proto__ / [[Prototype]]: the implicit prototype pointer on objects (often called an internal slot). It usually points to the constructor's prototype, can be reassigned to another object ornull, and is the backbone of inheritance and prototype chains.
1. Prototype Chain Inheritance
Key idea: the child prototype points to an instance of the parent.

- Inherits shared methods on the parent's prototype
- Cannot pass per-instance args to parent constructor when creating child instances
- Child prototype holds parent instance properties; reference-type properties become shared across instances
// Example
function Parent(name, age) {
this.name = name;
this.age = age;
this.arr = [1, 2, 3];
}
Parent.prototype.say = function () {
console.log(`${this.name} is ${this.age} years old`);
};
function Child() {}
Child.prototype = new Parent("niko", 18);
let c1 = new Child("zoyi", 1000);
let c2 = new Child();
c2.arr.push(4);
c2.gender = "girl";
console.log(c1.arr); // [1, 2, 3, 4] shared reference mutates globally
console.log(c1.gender); // undefined: assigning primitive creates own property
console.log(c2.gender); // girl
c1.say(); // niko is 18 years old
console.log(c1.constructor); // [Function: Parent]
- Since
Child.prototypeis aParentinstance,c1.say()looks upname/ageonc1first, then onChild.prototype.- After
Child.prototype = new Parent(), the defaultconstructorno longer points toChild; lookup usually resolves toParent.
2. Constructor Inheritance
Key idea: call the parent as a normal function in child constructor via call, so this points to child instance.
Only parent instance properties are inherited; methods on parent prototype are not (prototype chain is unchanged).
// Example
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.say = function () {
console.log(`${this.name} is ${this.age} years old`);
};
function Child(name, age, gender) {
Parent.call(this, name, age);
this.gender = gender;
}
let c1 = new Child("zoyi", 1000, "girl");
console.log(c1); // { name: "zoyi", age: 1000, gender: "girl" }
c1.say(); // c1.say is not a function
3. Combination Inheritance
Key idea: combine prototype chain inheritance and constructor inheritance.
Advantage: inherits both parent instance properties and prototype methods
Drawbacks:
- Parent constructor runs twice (once for child prototype, once for child instance), which is inefficient and less clean semantically.
- Child instance creates same-named properties again, shadowing those on prototype and adding overhead.
4. Parasitic Combination Inheritance

- Inherits both parent instance properties and prototype methods
- Calls parent constructor only once
- Uses
Object.create()as a bridge betweenChild.prototypeandParent.prototype- Note: members added to
Child.prototypebefore resetting it will be overwritten; usually fixconstructormanually
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.say = function () {
console.log(`${this.name} is ${this.age} years old`);
};
function Child(name, age) {
Parent.call(this, name, age);
}
// Child.prototype -> newObj -> Parent.prototype
Child.prototype = Object.create(Parent.prototype);
// Restore constructor after prototype replacement
Child.prototype.constructor = Child;
let c1 = new Child("zoyi", 1000);
c1.say(); // zoyi is 1000 years old
console.log(c1.constructor); // [Function: Child]
ES6 class inheritance: extends
Semantically, this is the standardized form of parasitic combination inheritance:
- In constructor,
super()runs parent initialization beforethiscan be used.Similar to
Parent.call(this, ...), but not equivalent to a plain function call. In instance methods,superpoints toParent.prototype; in static methods, it points toParent. - Builds prototype chain between
Child.prototypeandParent.prototype. - Builds static inheritance chain (
Child.__proto__ === Parent), so child can access parent static members.This is often equivalent to
Object.setPrototypeOf(Child, Parent); usinginstance.constructorto reach static methods is only an access path, not instance inheritance.