This is the 9th day of my participation in Gwen Challenge
First, define a class
function Animal (name) {
/ / property
this.name = name || 'Animal';
// Instance method
this.sleep = function(){
console.log(this.name + 'Sleeping'); }}// Prototype method
Animal.prototype.eat = function(food) {
console.log(this.name + 'Eating:' + food);
};
Copy the code
1. Prototype chain inheritance
Idea: Inheritance is implemented using a stereotype chain, with an instance of a superclass as the stereotype of a subclass
function Dog(){ }
Dog.prototype = new Animal();
Dog.prototype.name = 'dog';
var dog = new Dog();
console.log(dog.name); / / the dog
dog.eat('dog food'); // The dog is eating dog food
dog.sleep(); // The dog is sleeping
console.log(dog instanceof Animal); // true
console.log(dog instanceof Dog); // true
Copy the code
Features:
- Very pure inheritance, where an instance is an instance of a subclass and an instance of a parent class;
- New prototype methods/attributes in the parent class, accessible to all subclasses;
- Simple and easy to implement;
Disadvantages:
- You can add instance attributes to Dog instances in the Dog constructor. If new prototype properties and methods are added, they must be executed after statements such as new Animal();
- Multiple inheritance cannot be realized;
- All attributes from the stereotype object are shared by all instances;
- Cannot pass arguments to the parent constructor when creating a subclass instance.
Constructor inheritance
Idea: Add instances of subclasses using the parent class’s constructor by executing constructors on newly created objects using the call, apply methods
function Dog(name){
Animal.call(this);
this.name = name || 'wang wang';
}
var dog = new Dog();
console.log(dog.name); / / wang wang
dog.sleep(); // Wang Wang is sleeping
console.log(dog instanceof Animal); // false
console.log(dog instanceof Dog); // true
Copy the code
Features:
- In method 1, the subclass instance shares the parent class reference attribute.
- When creating a subclass instance, you can pass arguments to the parent class;
- Multiple inheritance can be implemented (call multiple parent objects);
Disadvantages:
- An instance is not an instance of a parent class, only an instance of a subclass;
- Only instance attributes and methods of the parent class can be inherited, not stereotype attributes/methods.
- Function reuse cannot be realized, each subclass has a copy of the parent class instance function, affecting performance;
3. Instance inheritance
Idea: Add a new feature to a parent class instance and return it as a subclass instance
function Dog(name){
var instance = new Animal();
instance.name = name || 'wang wang';
return instance;
}
var dog = new Dog();
console.log(dog.name); / / wang wang
dog.sleep(); // Wang Wang is sleeping
console.log(dog instanceof Animal); // true
console.log(dog instanceof Dog); // false
Copy the code
Features:
- There is no limit to how the call is made, and whether a new subclass () or subclass () returns the same object;
Disadvantages:
- An instance is an instance of a parent class, not a subclass;
- Multiple inheritance is not supported;
4. Copy inheritance
function Dog(name){
var animal = new Animal();
for(var p in animal){
Dog.prototype[p] = animal[p];
}
Dog.prototype.name = name || 'wang wang';
}
var dog = new Dog();
console.log(dog.name); // 'bark'
dog.sleep(); // Wang Wang is sleeping
console.log(dog instanceof Animal); // false
console.log(dog instanceof Dog); // true
Copy the code
Features:
- Support multiple inheritance;
Disadvantages:
- Low efficiency and high memory footprint (due to copying parent class attributes);
- Unable to get non-enumerable methods of the parent class (non-enumerable methods, not accessible using for in);
5. Original type inheritance
Idea: You don’t need to define a class to adopt old-style inheritance!! , passing in the argument obj, generates an object that inherits obj object
var animal = {
name: "Wang wang".age: 2,}function F(o) {
function C() {}
C.prototype = o;
return new C();
}
var dog = F(animal)
console.log(dog.name); / / wang wang
console.log(dog.age); / / 2
Copy the code
Features:
- Generate an object that inherits from an object directly from an object;
Disadvantages:
- It’s not class inheritance, it’s prototypal foundation, it lacks the concept of class;
6. Composite Inheritance (recommended)
Idea: Use construction inheritance and prototype chain composition
function Dog(name){
Animal.call(this);
this.name = name || 'wang wang';
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
var dog = new Dog();
console.log(dog.name); / / wang wang
dog.sleep(); // Wang Wang is sleeping
console.log(dog instanceof Animal); // true
console.log(dog instanceof Dog); // true
Copy the code
Features:
- It makes up for the defect of mode 2 by inheriting instance attributes/methods as well as prototype attributes/methods.
- Is an instance of both a subclass and a superclass;
- There is no reference attribute sharing problem;
- Can pass parameter;
- Function reusable;
Disadvantages:
- The parent constructor is called twice, generating two instances (the subclass instance masks the subclass prototype);
Parasitic inheritance
Idea: the original type + factory pattern solves the problem of combining inheritance to call the constructor twice; Create a function that simply encapsulates the inheritance process, then internally enhance the object in some way, and finally return the object;
// temporary transfer function
function obj(o) {
function Animal() {}
Animal.prototype = o;
return new Animal();
}
// Parasitic function
function create(o){
var Dog = obj(o);
// F can be extended
Dog.sleep = function(){
console.log(this.name + 'Sleeping')}return Dog;
}
var mydog = {
name: 'wang wang'.age: 1};var dog = create(mydog);
console.log(dog.name); / / wang wang
dog.sleep(); // Wang Wang is sleeping
Copy the code
Features:
- An extension of the original type inheritance
Disadvantages:
- There is still no concept of classes
8. Parasitic combination Inheritance (recommended)
Idea: The combination of parasitic inheritance and combined inheritance, perfect realization of inheritance without two superclass attributes
// This implementation does not fix constructor
function Dog(name){
Animal.call(this);
this.name = name || 'wang wang';
}
(function(){
// Create a class with no instance methods
var Super = function(){};
Super.prototype = Animal.prototype;
// Use the instance as the prototype of the subclass
Dog.prototype = newSuper(); }) ();var dog = new Dog();
console.log(dog.name); / / wang wang
dog.sleep(); // Wang Wang is sleeping
console.log(dog instanceof Animal); // true
console.log(dog instanceof Dog); // true
Copy the code
Supplement:
// Define a class
function Animal (name) {
/ / property
this.name = name || 'Animal';
// Instance method
this.sleep = function(){
console.log(this.name + 'Sleeping');
}
// Instance references attributes
this.features = [];
}
function Dog(name){}
Dog.prototype = new Animal();
var tom = new Dog('Tom');
var kissy = new Dog('Kissy');
console.log(tom.name); // "Animal"
console.log(kissy.name); // "Animal"
console.log(tom.features); / / []
console.log(kissy.features); / / []
tom.name = 'Tom-New Name';
tom.features.push('eat');
// Changes to members of the parent instance value type are not affected
console.log(tom.name); // "Tom-New Name"
console.log(kissy.name); // "Animal"
// Changes that reference a type member to a parent instance can affect other subclass instances
console.log(tom.features); // ['eat']
console.log(kissy.features); // ['eat']
// Cause analysis:
// 1. Execute Tom.features. push, first find the instance property of Tom object (not found), then go to the prototype object, i.e. If yes, insert values directly into the features property of the object.
/ / 2. In the console. The log (kissy. The features); From time to time. Ditto, not on the Kissy instance, so look for the prototype.
// 3. If the features attribute is present in the prototype object, it will be returned directly, but note that the features attribute value has been changed.
Copy the code
Features:
- Perfect;
Disadvantages:
- The implementation is complex;
9. Inheritance in ES6 (highly recommended)
The idea: ES6 inheritance through the syntactic sugar Class and Java and other object-oriented languages in the implementation of inheritance is very similar, but syntactic level of course, the essence of course is still through the prototype implementation. ES6 implements inheritance through the extends and super keywords, just like the object-oriented Java language.
class Animal{
constructor(name,age){
this.name = name || 'Animal';
this.age = age
this.hobbies = ['sleep'.'eat']}/* This is equivalent to the method hanging on the prototype */
static say(){ // Add a static method to the class
console.log('hello');
} // Do not place commas between methods
getname(){
console.log(this.name); }}class Dog extends Animal{
Subclass-specific attributes are written in front of arguments and superclass attributes are placed behind. arg ... An arG puts the extra arguments in a function into an array. * /
constructor(food,... arg){
super(... arg);// It is equivalent to calling the parent class and putting the extra parameters (attributes of the same parent class) into super to achieve the purpose of inheriting the attributes of the parent class
/* In inheritance, constructor must write under super super to use this. Super has a temporary deadband */
this.food = food
}
static sayState(){
console.log("I'm sleeping.")}sayAge(){
console.log("My year" + this.age + ', ');
}
sayFood(){
console.log('I'm eating.'+this.food)
}
}
var dog1 = new Dog('bone'."Wang wang".2);
Animal.say() / / how are you
Dog.sayState(); // I am sleeping
dog1.getname(); / / wang wang
dog1.sayAge(); // I am 2 years old
dog1.sayFood(); // I'm eating a bone
var dog2 = new Dog('dog food'."Prosperous wealth.".1);
dog2.hobbies.push("Play");
dog2.getname(); / / prosperous wealth
dog2.sayAge(); // I am 1 years old
dog2.sayFood(); // I'm eating dog food
console.log(dog1.hobbies) // [' sleep ',' eat ']
console.log(dog2.hobbies) // [' sleep ',' eat ',' play ']
Copy the code