Underlying principle of constructor/prototype in Javascript attributes

Source: Internet
Author: User

In Javascript, the constructor attribute is designed specifically for functions and exists in the prototype attribute of each function. This constructor saves a reference to the function. When defining a function (the Code is as follows,

Function F (){
// Some code
}

JavaScript performs the following actions internally:
Add a prototype attribute (prototype object) to the function ).
Add an additional constructor attribute for the prototype object and save a reference pointing to function F.

In this way, when we use function F as a user-defined constructor to create an object, the object instance will automatically save a constructor pointing to it (here is our user-defined constructor F) the prototype object has a property of _ proto __, so we can access all the properties and methods of the prototype of the constructor in every object instance, it is as if they are the instance's own.
Of course, this instance also has a constructor attribute (obtained from prototype). At this time, the role of constructor is obvious, because at this time, every object instance can access its constrcutor through the constrcutor object. See the following code:




[Javascript] view plaincopy




Var f = new F ();
Alert (f. constructor === F); // output true
Alert (f. constructor === F. prototype. constructor); // output true


We can use this feature to determine the object type, as shown in figure



[Javascript] view plaincopy




If (f. constructor === F ){
// Do something with F
}


In fact, the appearance of constructor was originally used to judge the object type, but the constructor attribute is changeable and untrusted.
We have a more secure and reliable determination method: instanceof operator.
The following code returns true

If (f instanceof F ){
// Do something with F
}.

Prototype chain inheritance. Because constructor exists on prototype objects, we can use constructor to find the most primitive constructor along the prototype chain, as shown in the following code:

Function Base (){
}
// Sub1 inherited from Base through prototype chain
Function Sub1 (){
}
Sub1.prototype = new Base ();
Sub1.prototype. constructor = Sub1;
Sub1.superclass = Base. prototype;
// Sub2 inherited from Sub1 through prototype chain
Function Sub2 (){
}
Sub2.prototype = new Sub1 ();
Sub2.prototype. constructor = Sub2;
Sub2.superclass = Sub1.prototype;
// Test prototype chain
Alert (Sub2.prototype. constructor );
// Function Sub2 (){}
Alert (Sub2.superclass. constructor );
// Function Sub1 (){}
Alert (Sub2.superclass. constructor. superclass. constructor );
// Function Base (){}

The above example is just to illustrate the role of constructor in the prototype chain. A more practical point is that a subclass object can obtain all the attributes and methods of its parent class, which is called inheritance, we have a lot to analyze and discuss about inheritance. This article will not be discussed here.
A trap that is easy to fall into (gotchas) mentioned earlier that constructor is easy to change because the prototype attribute of the function is easy to change. In our use, the popular encoding method is used to illustrate the problem, see the following sample code:

Function F (){

}
F. prototype = {
_ Name: Eric,
GetName: function (){
Return this. _ name;
}
}

There is no problem with this method, but you will find that the following code is invalid:
Var f = new F ();
Alert (f. constructor === F); // output false
What's going on? Isn't F the constructor of instance object f?
Of course! The prototype of the constructor F is overwritten by the developer. In this way, the original prototype object is replaced by an object literal.
The newly created Object {} is only an instance of the Object. The system (or the browser) does not automatically add a constructor attribute on {} during parsing, this is the exclusive operation for function creation. The parser will do this operation only when you declare the function.
However, you will find that constructor does not exist. The following code can test its existence:
Alert (typeof f. constructor = 'undefined'); // output false
Now, where did the constructor come from?
We want to analyze the object literal number {}.
Because {} is a shorthand for creating objects, {} is equivalent to new Object ().
Since {} is an Object instance, it naturally obtains a reference _ proto __of the prototype attribute pointing to the Object () of the constructor. prototype has a constructor attribute pointing to the Object itself. So we can see that this constructor is actually the constructor of Object. prototype. The following code can verify its conclusion:
Alert (f. constructor === Object. prototype. constructor); // output true
Alert (f. constructor === Object); // also output true
One solution is to manually restore his constructor. The following code solves this problem very well:

Function F (){
}
F. prototype = {
Constructor: F,/* reset constructor */
_ Name: Eric,
GetName: function (){
Return this. _ name;
}
};

After that, everything will return to normal. constructor re-obtains the reference of the constructor. We can test the above Code again and return true this time.
Var f = new F ();
Alert (f. constructor === F); // output true this time ^
Q: Why is there a constructor on the constructor? Where did it come from?
Careful friends will find that there is a constructor like a built-in JavaScript constructor, such as Array, RegExp, String, Number, Object, and Function:
Alert (typeof Array. constructor! = 'Undefined'); // output true
Tests show that this object is not the same as constructor on prototype. They coexist:
Alert (typeof Array. constructor! = 'Undefined'); // output true
Alert (typeof Array. prototype. constructor = Array); // output true
However, this is easy to understand, because constructor is also a function.
A Function indicates that it is an instance object of the Function constructor. Naturally, it also has an internal reference _ proto _ pointing to Function. prototype.
Therefore, we can easily conclude that the constructor (constructor on the constructor is not prototype) is actually a reference to the Function constructor:
Alert (Array. constructor === Function); // output true
Alert (Function. constructor === Function); // output true

OK. Since now, constructor has been revealed. You are not new to it.

This article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.