Thoroughly understand JavaScript prototypes

Source: Internet
Author: User
Tags hasownproperty

Prototypes are a relatively difficult concept in JavaScript, with more primitive-related properties, objects with "[[prototype]]" Properties, function objects with "prototype" properties, and prototype objects with "constructor" properties.

This article is in order to understand the prototype and the relationship of these attributes related to the prototype.

I believe that through this article will be able to clearly understand the prototype, start the prototype journey now.

Understanding prototypes

Before starting the introduction of prototypes, first come to know what is a prototype?

In JavaScript, the prototype is also an object, the prototype can implement the object's property inheritance,JavaScript object contains a "[[]]" internal property, which corresponds to the object's prototype.

"[[Prototype]]" is not directly accessible as an intrinsic property of an object. So to make it easier to see the prototypes of an object, Firefox and Chrome provide a non-standard (not all browsers-supported) accessor for "__proto__" (ECMA introduces standard object prototype accessors) Object.getprototype (Object) ").

Example analysis

Here's an example of a prototype-related concept:

function person (name, age) {    this.name = name;    this.age =function() {Console.log (this.age + "years old");};} New Person ("would",;);        

In the code above, a would object was created by the person's constructor. Here's a look at the prototype through the will object step-by-step.

Step 1: View the object's prototype

The following code allows you to see the prototype of the object will:

Console.log (will.__proto__); Console.log (Will.constructor);

Results Analysis:

    • The "Person {}" object is the prototype of the object will, and with chrome expansion you can see that "person {}" is a prototype object and also has the "__proto__" attribute (the prototype for the prototype).
    • In this code, the "constructor" attribute is also used. in the JavaScript prototype object , there is also a "constructor" property that corresponds to the constructor that creates all instances of the prototype .
      • By "constructor" This property, we can judge whether an object is not an array type
        function IsArray (myArray) {    return myArray.constructor.toString (). IndexOf ("Array") >-1;}  
      • Here, the wouldobject itself does not have the "constructor" attribute , but through the prototype chain lookup, the "constructor" attribute of the'll prototype (will.__proto__) is found, and the person function is obtained.

Step 2: View the prototype of the object's prototype (WILL.__PROTO__)

Since Will's prototype "person {}" is also an object, then we can also look at "the prototype of will.__proto__".

Run the following code:

Console.log (will.__proto__ = = = Person.prototype); Console.log (person.prototype.__proto__); Console.log ( Person.prototype.constructor); Console.log (Person.prototype.constructor = = = person);

Results Analysis:

    • First Look at "will.__proto__ = = = Person.prototype", in JavaScript, each function has a prototype property, when a function is used as a constructor to create an instance, The prototype property value of the function is assigned as a prototype to all object instances (that is, the __proto__ property of the instance is set), that is, the prototype of all instances refers to the prototype property of the function. Once you understand the prototype property of the constructor, you must understand why the first sentence turns out to be true.
      • The prototype property is unique to the function object and will not have a property if it is not a function object.
    • When you get the prototype of the will object using the "person.prototype.__proto__" statement, you will get the object {}, and you will see that the prototypes of all objects will be traced back to the object {}.
    • For the prototype object "Person.prototype" of "constructor", according to the previous introduction, will correspond to the person function itself.

As you can see above,the "Person.prototype" object and the person function object are referenced by the "constructor" and "prototype" properties (there will be a diagram showing this cross-referencing relationship later).

Step 3: View the object's prototype

As you can see from the previous section, the prototype of Will's prototype is the object {}. In fact, in JavaScript, the prototypes of all objects are traced back to the object {}.

Here's a piece of code to see the object {}:

Console.log (person.prototype.__proto__ = = = Object.prototype); Console.log (typeof Object); Console.log ( Object); Console.log (Object.prototype); Console.log (object.prototype.__proto__); Console.log ( Object.prototype.constructor);  

You can see the following code:

    • The object is itself a function object.
    • Since it is an object function, there will definitely be a prototype property, so you can see that the value of "Object.prototype" is the prototype object of "object {}".
    • Conversely, when accessing the "constructor" property of the "Object.prototype" object, the OBEJCT function is obtained.
    • In addition, when you get the prototype of the object prototype through "object.prototype.__proto__", you will get "null", which means that the "object {}" prototype object is the end of the prototype chain.

Step 4: View the prototype of the object function

In the example above, the person is a constructor, and in JavaScript the function is also an object, so we can also find the prototype of the person function object through the "__proto__" property.

Console.log (person.__proto__ = = = Function.prototype); Console.log (Person.constructor = = Function) Console.log (typeof function); Console.log (function); Console.log (Function.prototype); Console.log ( function.prototype.__proto__); Console.log (Function.prototype.constructor);   

Results Analysis:

    • In JavaScript, there is a function object (like object), which is itself an object, and all functions (including function,object) of the prototype (__proto__) are "Function.prototype".
    • A function object is a prototype property, which corresponds to the "function () {}" object.
    • A Function object, as an object, has a "__proto__" property that corresponds to "Function.prototype", that is, "function.__proto__ = = = Function.prototype"
    • For the prototype object "Function.prototype" of the Function, the "__proto__" property of the prototype object corresponds to "object {}"

Compare prototype and __proto__

For the two properties "prototype" and "__proto__" may be confused, "Person.prototype" and "person.__proto__" are completely different.

Here is a brief introduction to "prototype" and "__proto__":

    • For all objects, there is the __proto__ property, which is the prototype of the object that should be
    • For a function object, in addition to the __proto__ property, there is a prototype property, and when a function is used as a constructor to create an instance, the prototype property value of the function is assigned to all object instances (that is, the __proto__ of the set instance). Properties)
Illustration example

Based on the analysis of the examples above, I believe you must have learned a lot about the prototype.

But now it's pretty messy, a prototype, a prototype for a while, a function,object,constructor,prototype and so on.

Now I'm going to plot the results/relationships in the example above, and I believe this picture will make you feel enlightened.

For the following summary:

    • All objects have the "__proto__" property, which is a prototype of the object that should be
    • All function objects have the "prototype" property, and the value of the property is assigned to the "__proto__" property of the object created by the function
    • All prototype objects have a "constructor" property that corresponds to the constructor that creates all instances of the prototype
    • function objects and prototype objects are interrelated through the "prototype" and "constructor" properties
Examples of improvements through prototypes

In the example above, the "GetInfo" method is a member of the constructor's person, and each instance contains a "getInfo" method when constructing two instances from the individual.

New person ("would",;);  New Person ("Wilber"); 

As previously understood, the prototype is to facilitate the implementation of property inheritance, so the "GetInfo" method can be used as a property of the person prototype (PERSON.__PROTO__), so that all instances can be inherited by the prototype way to use the "GetInfo" method.

So make the following changes to the example:

function person (name, age) {    this.name = name;    this.age =function() {Console.log (this.age + "years old");};       

The result of the modification is:

Prototype chain

Because each object and prototype has a prototype, the object's prototype points to the parent of the object, and the parent's prototype points to the parent's parent, and the prototype layer joins together to form the prototype chain.

In the article "Understanding the scope chain of JavaScript," The identifiers and attributes are described through the scoping chain and the lookup of the prototype chain.

Let's continue looking at the attribute lookup based on the prototype chain.

Property Lookup

When looking up a property of an object, JavaScript traverses the prototype chain up until it finds the property of the given name, until the lookup reaches the top of the prototype chain (that is, "Object.prototype"), and if the specified property is still not found, it returns undefined.

See an example:

function person (name, age) {    this.name = name;    this.age = Age ;} Person.prototype.MaxNumber = 9999; person.__proto__. Minnumber = -9999;  New person ("would",Console.log); MaxNumber); // 9999Console.log (would. Minnumber); // undefined             

In this example, the "Person.prototype" and "person.__proto__" are added to the two prototype objects "MaxNumber" and "Minnumber" attribute, here you need to understand "prototype" and "__proto_ _ "The difference is.

"Person.prototype" corresponds to the person who constructs all instances of the prototype, that is, "Person.prototype" is part of these instances of the prototype chain, so when these instances for property lookup, it will refer to the " Person.prototype the properties in the.

Property hiding

When looking for a property through the prototype chain, the first thing to look for is the property of the object itself, and if it cannot find it, it will continue to follow the prototype chain.

In this way, if you want to override some of the properties on the prototype chain, we can introduce these properties directly into the object to achieve the effect of property shadowing.

See a simple example:

functionPerson (name, age) {this.name = name; this.age = Age;} Person.prototype.getInfo = function () {Console.log ( Span style= "color: #0000ff;" >this.name + "is" + this.age + "years old" var'll = new person ("would", 28function () {Console.log ("GetInfo Method from would instead of prototype ");}; Will.getinfo (); // GetInfo method from would instead of prototype  span>               
How object creation affects the prototype chain

At the beginning of this article, the will object is created with the person constructor, so the prototype of would (WILL.__PROTO__) is "Person.prototype".

Again, we can create an object in the following way:

var July = {    name: "July",    age:28,    function() {Console.log (this.age + "years old ");},}console.log (July.getinfo ());      

When an object is created in this way, the prototype chain becomes, the prototype of the July object is "Object.prototype" which means that the way the object is built affects the form of the prototype chain.

hasOwnProperty

"hasOwnProperty" is a method of "Object.prototype" that determines whether an object contains custom attributes rather than properties on the prototype chain, because "hasOwnProperty" is a JavaScript The only function that handles properties but does not look for a prototype chain.

I believe you remember the first example of this, through will we can access the "constructor" attribute and get the constructor of will. With the function "hasOwnProperty" here, you can see that the will object does not have a "constructor" attribute.

As you can see from the output below, "constructor" is the property of Will's prototype (WILL.__PROTO__), but through the lookup of the prototype chain, the will object can discover and use the "constructor" property.

"hasOwnProperty" also has an important usage scenario that is used to traverse the properties of an object.

functionPerson (name, age) {THIS.name =NameThis.age =Age;} Person.prototype.getInfo =function() {Console.log (THIS.name + "is" +This.age + "years old");};var would =new person ("would", 28 for (var attr in would) { Console.log (attr);} // Name// Age// Getinfofor ( Span style= "color: #0000ff;" >var attr  would" {if< Span style= "color: #000000;" > (Will.hasownproperty (attr)) {Console.log (attr);}} // Name// age                 
Summarize

In this paper, we introduce the concept of JavaScript-related concepts, and the following points can be summed up for prototypes:

    • All objects have a "[[[Prototype]]" property (accessed through __proto__), which corresponds to the prototype of the object
    • All function objects have the "prototype" property, and the value of the property is assigned to the "__proto__" property of the object created by the function
    • All prototype objects have a "constructor" property that corresponds to the constructor that creates all instances of the prototype
    • function objects and prototype objects are interrelated through the "prototype" and "constructor" properties

Also to emphasize is the example of the beginning of the article, as well as the example of a "normal object", "function object" and "prototype object" between the diagram, when you are confused about the relationship between the prototype, think of this picture (or redraw a diagram of the current object), you can clarify the complexity of the relationship.

Through these introductions, I believe we can have a clear understanding of the prototype.

Thoroughly understand JavaScript prototypes

Related 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.