inheritance
Constructor, stereotype, and instance relationships
- Each constructor has a prototype object
- The stereotype has an attribute that points back to the constructor
- The instance has an internal pointer to the prototype
Prototype chain
- If a stereotype is an instance of another type, that stereotype itself has an internal pointer to another stereotype, which in turn has a pointer to another constructor. This creates a chain of prototypes.
Combinatorial inheritance
- A combination of prototype chains and stolen constructors brings together the best of both.
- The basic idea is to use stereotype chains to inherit properties and methods on stereotypes, and to inherit instance properties by stealing constructors.
- This allows methods to be reused on prototypes, while allowing each instance to have its own attributes
Function SuperType(name) {this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() { console.log(this.name); } function SubType(name, age) {// Supertype. call(this, name); this.age = age; } SubType.prototype = new SuperType(); SuperType.prototype.sayAge = function() { console.log(this.age); } let instance1 = new SubType("n1", 19); instance1.colors.push("black"); console.log(instance1.colors); //["red", "blue", "green", "black"] instance1.sayName(); //n1 instance1.sayAge(); //19 let instance2 = new SubType("Greg", 27); console.log(instance2.colors); //["red", "blue", "green"] instance2.sayName(); //Greg instance2.sayAge(); / / 27Copy the code
Primary inheritance
- Use case: You have an object and want to create a new object based on it.
- Es5 normalizes the concept of old-style inheritance by adding the object.create () method, which takes two parameters: an Object to be the prototype for the new Object, and an Object to define additional properties for the new Object (the second is optional). With only one argument, object.create () has the same effect as the Object () method here
- Old-style inheritance is ideal for situations where you don’t need to create a separate constructor, but you still need to share information between objects
let person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; let anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); let yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); // let person1 = object. create(person, {name: {value: "Grat" } }) console.log(person1.name); //"Grat"Copy the code
Parasitic inheritance
- The idea behind parasitic inheritance is similar to the parasitic constructor and factory pattern: Create a function that implements inheritance, enhance an object in some way, and then return that object
- Parasitic inheritance is also suitable for scenarios where the main focus is on objects, not types and constructors.
let person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
function createAnther(original) {
let clone = Object.create(original);
clone.sayHi = function() {
console.log("hi");
};
return clone;
}
let anotherPerson = createAnther(person);
anotherPerson.sayHi(); //hi
Copy the code
Parasitic combinatorial inheritance
- Combinatorial inheritance has efficiency problems. The main efficiency issue is that the superclass constructor is always called twice: once when the subclass prototype is created and once in the subclass constructor
- Essentially, the subclass stereotype ends up containing all instances of the superclass object, and the subclass constructor simply overrides its own stereotype at execution time.
function inheritPrototype(subType, superType) { let prototype = Object.create(superType.prototype); Prototype. constructor = subType; subType.prototype = prototype; } function SuperType(name) { this.name = name; this.color = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() { console.log(this.name); } function SubType(name, age) { SuperType.call(this, name); // Call SuperType() this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function() { console.log(this.age); }Copy the code
- The prototype chain remains unchanged, so the instanceof operator and isPrototypeOf() methods are valid. Parasitic composite inheritance is the best model for reference type inheritance