Today I want to talk about prototype in javascript.
Generally, an object in javascript is a pointer to prototype and a list of its own properties.Javascript adopts the concept of copy-on-write when creating objects.
Only the constructor has the prototype attribute.The prototype chain inheritance is to create a new pointer pointing to the prototype attribute of the constructor. The prototype attribute is special because it is determined by the traversal mechanism when reading the attribute in javascript. Essentially, it is a common pointer. Constructors include:
1. Object2.Function3. Array4.Date5. String
Here are some examples.
// Each function has a default prototype attribute, and the constructor of this prototype points to this function by default. // note Person. constructor is not equal to Person. prototype. constructor. function instance comes with the constructor attribute function Person (name) {this. name = name ;}; Person. prototype. getName = function () {return this. name ;}; var p = new Person ("ZhangSan"); console. log (Person. prototype. constructor = Person); // true console. log (p. constructor = Person); // true, this is because p itself does not contain the constructor attribute, so here actually calls Person. prototype. constructor
Our purpose is to indicate
1. indicates that the Person inherits from Animal2. indicates that p2 is an instance of the Person.
Let's modify the direction of the prototype attribute so that Person can obtain the method in the prototype attribute of Animal. That is, the Person inherits from Animal (the Person is a beast)
Function Person (name) {this. name = name ;}; Person. prototype. getName = function () {return this. name ;}; var p1 = new Person ("ZhangSan"); console. log (p. constructor = Person); // true console. log (Person. prototype. constructor = Person); // true function Animal () {} Person. prototype = new Animal (); // Person is not used. prototype = Animal. prototype, because new has other functions. Var p2 = new Person ("ZhangSan"); // (p2-> Person. prototype-> Animal. prototype, so p2.constructor is actually Animal. prototype. constructor) console. log (p2.constructor = Person); // The output is false, but our intention is to be true here, indicating that p2 is an instance of Person. In this case, Objective 1 is achieved, and Objective 2 is not.
But if we fix it like this
Person. prototype = new Animal (); Person. prototype. constructor = Person;
In this case, p2.consturctor is correct and points to Person, indicating that p2 is an instance of the Person class, but a new problem occurs. In this case, Objective 2 is achieved, and Objective 1 is not. Objective 1 and Objective 2 conflict with each other at this time because prototype expresses two conflicting meanings,
1 indicates who the parent class is. 2. Copy it as the prototype of your instance.
Therefore, we cannot directly use the prototype attribute to indicate who the parent class is. Instead, we use the getPrototypeOf () method to know who the parent class is.
Person. prototype = new Animal (); Person. prototype. constructor = Person; var p2 = new Person ("ZhangSan"); p2.constructor // display function Person () {} Object. getPrototypeOf (Person. prototype ). constructor // display function Animal (){}
The two concepts are separated. In fact, 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 () is executed, new does the following:
Create a blank object
Create a pointer to Person. prototype
Pass this object to the constructor using the this keyword and execute the constructor.
Specifically, in the following code,
Person.prototype.getName = function() { }
If we use
Var person = new Person (); actually similar to var person = new Object (); person. getName = Person. prototype. getName;
Therefore, when you call a method using person. getName (), this points to the newly created object instead of the prototype object.
This is actually used when new functions are added to existing functions. We can extend the existing method as follows:
//Function myFunc is basically the same as var myFunc = new Function (); function myFunc () {} myFunc = function (func ){
// You can do other things hereReturn function (){
// You can do other things hereReturn func. apply (this, arguments) ;}} (myFunc)
You can also use this in the Function. prototype Method to directly access the object pointed to by myFunc in the code above.
function myFunc () {}
if (!Function.prototype.extend) { Function.prototype.extend = function(){ var func = this; return function(){ func.apply(this,arguments); } }};var myFunc = myFunc.extend();
Summary:
If Person. prototype = Animal. prototype is used to indicate that Person inherits from Animal, the instanceof method will also show that p is also an Animal instance and return true.
This method is not used for the following two reasons:
1. A new object is created to avoid setting Person. prototype. constructor = Person also causes Animal. prototype. the value of constructor is changed to Person, but a constructor instance attribute is dynamically assigned to the newly created object. In this way, the attribute constructor on the instance overwrites Animal. prototype. constructor, so that the Person. prototype. constructor and Animal. prototype. contructor are separated.
2. attributes of this object of Animal cannot be passed to Person.