When using object-oriented programming, the inheritance relationship between objects is naturally indispensable! The prototype is a very important way to implement JavaScript inheritance!
Let’s first look at the following code:
function person (name, age) {
this.name = name;
this.age = age;
}
person.prototype.getInfo = function() {
alert("My name is " this.name ", and I have " this.age " years old");
}
var zhangchen = new person("zhangchen", 23);
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;
From the running results, we can see that the zhangchen object created through the keyword new inherits the getInfo( defined through the prototype in person )method. Let's take a closer look at how the newly created zhangchen object inherits the attributes and methods of the person object.
Prototype: In object-oriented programming using JavaScript, prototype objects are a core concept. The name comes from the concept that objects in JavaScript are created as copies of existing instance (i.e. prototype) objects. Any properties and methods of this prototype object will appear as properties and methods of the object created from the prototype's constructor. We can say that these objects inherit properties and methods from their prototype. When creating the zhangchen object:
var zhangchen = new company( "zhangchen", 23);
The object referenced by zhangchen will inherit properties and methods from its prototype, which comes from the properties of the constructor (in this case, the function person).
In JavaScript, every function has an attribute called prototype, which is used to refer to the prototype object. This prototype object in turn has a property called constructor, which in turn refers to the function itself. This is a circular reference. The following figure better illustrates this circular relationship.
Figure 1 Circular relationship
Now, when creating an object with a function (person in the example above) via the new operator, the obtained object will inherit the properties of person.prototype. In the image above, you can see that the person.prototype object has a constructor property that refers back to the person function. This way, each person object (inherited from person.prototype) has a constructor property that refers back to the person function.
We can use the following code to verify whether this loop is correct:
function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype.getInfo = function() {
alert("My name is " this.name ", and I have " this.age " years old");
}
var zhangchen = new person("zhangchen", 23);
alert(zhangchen.constructor == person.prototype.constructor); //output true
alert(zhangchen.constructor == person); // output true
alert(person.prototype.isPrototypeOf(zhangchen)) ; //output true
Where does the call to the "isPrototypeOf()" method in the above code come from? Is it from person.prototype object? No, in fact, there are other methods called toString, toLocaleString, and valueOf in person.prototype and person instances, but none of them come from person.prototype. Rather, it comes from Object.prototype in JavaScript, which is the ultimate base prototype for all prototypes. (The prototype of Object.prototype is null.)
In the above example, zhangchen.prototype is the object. It is created by calling the Object constructor (although it is not visible) which is equivalent to executing the following code:
zhangchen.prototype = new Object();
So, just as person instances inherit person.prototype, zhangchen.prototype inherits Object.prototype. This causes all zhangchen instances to also inherit the methods and properties of Object.prototype.
Prototype Chain: Every JavaScript object inherits a prototype chain, and all prototypes terminate in Object.prototype. Note that this inheritance is between active objects. It differs from the common concept of inheritance, which refers to inheritance between classes that occurs when they are declared. Therefore, JavaScript inheritance is more dynamic. It achieves this using a simple algorithm as follows: When you try to access a property/method of an object, JavaScript checks whether the property/method is defined in that object. If not, the object's prototype is checked. If not, then the prototype of the object's prototype is checked, and so on, all the way to Object.prototype. The following figure illustrates this parsing process:
Figure 2 The parsing process of toString() method
From the above parsing process, if property/method X is defined in the object, the property/method with the same name will be hidden in the prototype of the object. For example, you can override the toString method of Object.prototype by defining the toString method in person.prototype.
Look at the following code again:
function person(name , age) {
this.name = name;
this.age = age;
}
person.prototype.getInfo = function() {
alert("My name is " this .name ", and I have " this.age " years old");
}
var zhangchen = new person("zhangchen", 23);
var luomi = new person("luomi", 23);
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;
luomi.getInfo(); // output My name is luomi, and I have 23 years old ;
luomi.getInfo = function() {
alert("here can rewrite the function of getInfo!");
}
luomi.getInfo(); //here can rewrite the function of getInfo!
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;
As you can see from the running results, although each instance of person inherits methods in person.prototype, but we can also redefine methods in the prototype object in the instantiated object, and it will not affect other instances!
The above is my understanding of prototypes and prototype chain inheritance methods. Please refer to (
JavaScript: Using Object-Oriented Technology to Create Advanced Web Applications). I hope everyone can discuss it together!