prototype and Inheritance in Javascript

  • 2021-07-16 01:48:49
  • OfStack

Typically, an object in an javascript is a pointer to an prototype and a list of its own attributes. javascript uses the concept of copy-at-write when creating objects.

Only constructors have the prototype attribute, and prototype chain inheritance creates a new pointer to the constructor's prototype attribute.

The prototype attribute is special because of the traversal mechanism for reading the attribute at javascript. In essence, it is an ordinary pointer.

Constructors include:

1.Object
2.Function
3.Array
4.Date
5.String

Let's give some examples below


// Each function Have both 1 Default properties prototype , and this prototype Adj. constructor Points to this function by default 
// Attention Person.constructor  Not equal to  Person.prototype.constructor. Function Instance comes with constructor Attribute 
functionPerson(name){
this.name = name;
};
Person.prototype.getName =function(){
returnthis.name;
};
var p =newPerson("ZhangSan");
console.log(Person.prototype.constructor===Person);// true
console.log(p.constructor===Person);// true , This is because p Does not contain itself constructor Property, so what is actually called here is Person.prototype.constructor

Our purpose is to show that

1. Indicate that Person inherits from Animal

2. Show that p2 is an example of Person

We modify the pointing of the prototype attribute under 1 so that Person can get the method in the prototype attribute in Animal. That is, Person inherits from Animal (man is a beast)


functionPerson(name){
this.name = name;
};
Person.prototype.getName =function(){
returnthis.name;
};
var p1 =newPerson("ZhangSan");
console.log(p.constructor===Person);// true
console.log(Person.prototype.constructor===Person);// true
functionAnimal(){}
Person.prototype =newAnimal() ; // The reason why it is not adopted Person.prototype = Animal.prototype, Is because new  There are other functions, which are finally summarized. 
var p2 =newPerson("ZhangSan");
//(p2 -> Person.prototype -> Animal.prototype,  So p2.constructor In fact, it is Animal.prototype.constructor)
console.log(p2.constructor===Person);//  Output is false , But our intention is to make this place true Of, indicating that p2 Yes Person Gets or sets an instance of the. Purpose at this time 1 Achieved, the purpose 2 Not reached. 

But if we fix it this way


Person.prototype = new Animal() ; 
Person.prototype.constructor = Person ; 

At this point p2.consturctor is correct, pointing to Person, indicating that p2 is an instance of the Person class, but a new problem arises. At this time, goal 2 was achieved, but goal 1 was not achieved.

Purpose 1 and Purpose 2 contradict each other at this time because prototype expresses two contradictory meanings at this time.

1. Indicates who the parent class is

2. Copy as a prototype of your own instance

So instead of using the prototype attribute directly to indicate who the parent class is, we use the getPrototypeOf () method to know who the parent class is.


Person.prototype =newAnimal() ; 
Person.prototype.constructor=Person ; 
var p2 =newPerson("ZhangSan");
p2.constructor// Display  function Person() {}
Object.getPrototypeOf(Person.prototype).constructor// Display  function Animal() {}

By using the hasOwnProperty () method, it is clear when the instance attribute is accessed and when the prototype attribute is accessed

What did new do?

When the code var p = new Person () executes, new does the following:

Create 1 blank object

Create a pointer to Person. prototype

Pass this object into the constructor through the this keyword and execute the constructor.

Specifically, in the following code,

Person.prototype.getName =function(){}

If we pass


var person =newPerson();
 In fact, it is similar to 
var person =newObject();
person.getName =Person.prototype.getName;

So when a method is called through person. getName (), this points to the newly created object, not the prototype object.

This is actually used when adding new functions to existing functions. We can extend the existing methods as follows:


//function myFunc  The writing of is basically equal to  var myFunc = new Function();
function myFunc (){
}
myFunc =function(func){
    // You can do something else here 
returnfunction(){
           // You can do something else here 
return func.apply(this,arguments);
}
}(myFunc)

You can also access the object pointed to by the myFunc of the above code directly through this in the Function. prototype method


function myFunc (){
}
if(!Function.prototype.extend){
Function.prototype.extend =function(){
var func =this;
returnfunction(){
func.apply(this,arguments);
}
}
};
var myFunc = myFunc.extend();

Summary 1

If Person. prototype = Animal. prototype is used to indicate that Person inherits from Animal, the instanceof method also shows that p is also an instance of Animal and returns true.

There are two reasons why this method is not adopted:

1. new creates a new object, which avoids setting Person. prototype. constructor = Person causing the value of Animal. prototype. constructor to become Person, but dynamically gives the newly created object an constructor instance property. Thus, the attribute constructor on the instance overrides Animal. prototype. constructor, so that Person. prototype. constructor and Animal. prototype. contructor are separated.

2. The properties of this object of Animal itself cannot be passed to Person

However, calling the constructor directly like the following may fail or have other effects.

Person.prototype =newAnimal();

To avoid this, we introduce an intermediate function. So the right thing to do is


Person.prototype =(funtion(){
     function F(){};
     F.prototype =Animal.prototype
     returnnew F();
})()

Related articles: