Explanation of the original JavaScript model and prototype chain

Source: Internet
Author: User

Explanation of the original JavaScript model and prototype chain

This article mainly introduces the original JavaScript model and prototype chain. This article describes the basic concepts of private variables and functions, static variables and functions, instance variables and functions, prototype and prototype chain, for more information, see

 

 

Each object in javascript has a built-in prototype attribute. The prototype attribute of the object in Javascript is interpreted as returning reference to the prototype of the object. It means that the prototype property stores a reference to another JavaScript Object, which serves as the parent object of the current object.

Copy the Code as follows:


A. prototype = new B ();


Understanding prototype should not confuse it with inheritance. Prototype of A is an instance of B. It can be understood that A clones all the methods and attributes of B. A can use the methods and attributes of B. Here we emphasize cloning rather than inheritance. This can happen: prototype of A is an instance of B, and prototype of B is also an instance of.

 

Continue with the following analysis:

Private variables and functions

Variables and functions defined in a function cannot be accessed externally without providing external interfaces, that is, private variables and functions of the function.

Copy the Code as follows:


<Script type = "text/javascript">
Function Box (){
Var color = "blue"; // Private variable
Var fn = function () // Private function
{

 

}
}
</Script>


In this way, variables color and fn cannot be accessed outside the function object Box, and they become private:

Copy the Code as follows:


Var obj = new Box ();
Alert (obj. color); // The undefined dialog box is displayed.
Alert (obj. fn); // same as above

 

Static variables and functions

After defining a function, click ". the added attributes and functions are still accessible through the object, but cannot be accessed by its instance. Such variables and functions are called static variables and static functions respectively.

 

Copy the Code as follows:


<Script type = "text/javascript">
Function Obj (){};

 

Obj. num = 72; // static variable
Obj. fn = function () // static function
{

}

Alert (Obj. num); // 72
Alert (typeof Obj. fn) // function

Var t = new Obj ();
Alert (t. name); // undefined
Alert (typeof t. fn); // undefined
</Script>

 

Instance variables and functions

In object-oriented programming, apart from some library functions, we still want to define some attributes and methods at the same time when the object is defined, and can be accessed after instantiation. js can also do this.

Copy the Code as follows:


<Script type = "text/javascript">
Function Box (){
This. a = []; // instance variable
This. fn = function () {// instance method

 

}
}

Console. log (typeof Box. a); // undefined
Console. log (typeof Box. fn); // undefined

Var box = new Box ();
Console. log (typeof box. a); // object
Console. log (typeof box. fn); // function
</Script>

 

Add new methods and attributes for instance variables and Methods

Copy the Code as follows:


<Script type = "text/javascript">
Function Box (){
This. a = []; // instance variable
This. fn = function () {// instance method

 

}
}

Var box1 = new Box ();
Box1.a. push (1 );
Box1.fn = {};
Console. log (box1.a); // [1]
Console. log (typeof box1.fn); // object

Var box2 = new Box ();
Console. log (box2.a); // []
Console. log (typeof box2.fn); // function
</Script>

 

In box1, a and fn are modified, but box2 is not changed. Because arrays and functions are both objects and reference types, this shows that the attributes and methods in box1 have the same name as those in box2, but they are not a reference, but a copy of the attributes and methods defined by the Box object.

This is no problem for attributes, but it is a big problem for methods, because methods are doing the same function, but there are two copies, if a function object has thousands of methods and instance methods, each of its instances must copy thousands of methods. This is obviously not scientific. Can this be swollen, prototype came into being.

Basic Concepts

Each function we create has a prototype attribute, which is a pointer to an object. The purpose of this object is to include the attributes and methods that can be shared by all instances of a specific type. Prototype is the prototype of the object instance created by calling the constructor.

The advantage of prototype is that the object instance can share its attributes and methods. That is to say, you do not need to add the Defined Object Information to the constructor, but you can directly add the information to the prototype. The main problem with using constructors is that each method must be created in each instance.

In JavaScript, there are two types of values: Original Value and object value. Each object has an internal prototype, which is usually called a prototype. The prototype value can be an object or null. If its value is an object, the object must have its own prototype. In this way, a linear chain is formed, which is called the prototype chain.

Description

A function can be used as a constructor. In addition, only functions have the prototype attribute and can be accessed, but the object instance does not have this attribute. There is only one internal inaccessible _ proto _ attribute. _ Proto _ is a mysterious link to a prototype. According to the standard, __proto _ is not made public, that is, it is a private property, but the Firefox engine exposes it as a common property, we can access and set it externally.

Copy the Code as follows:


<Script type = "text/javascript">
Var Browser = function (){};
Browser. prototype. run = function (){
Alert ("I'm Gecko, a kernel of firefox plugin ");
}

 

Var Bro = new Browser ();
Bro. run ();
</Script>

 

When we call Bro. run () method, because Bro does not have this method, so he will go to his _ proto _ to find, that is, Browser. prototype, so the run () method is finally executed. (Here, the upper-case letters of a function represent constructors to distinguish between common functions)

When a constructor is called to create an instance, the instance contains an internal pointer (_ proto _) pointing to the prototype of the constructor, this connection exists between the instance and the prototype of the constructor, rather than between the instance and the constructor.

Copy the Code as follows:


<Script type = "text/javascript">
Function Person (name) {// Constructor
This. name = name;
}

 

Person. prototype. printName = function () // prototype object
{
Alert (this. name );
}

Var person1 = new Person ('byron '); // instantiate an object
Console. log (person1. _ proto _); // Person
Console. log (person1.constructor); // you can see what it is.
Console. log (Person. prototype); // point to the prototype object Person
Var person2 = new Person ('frank ');
</Script>


The Person instance person1 contains the name attribute, and an _ proto _ attribute is automatically generated. This attribute points to the Person prototype and can access the printName method defined in the prototype, this is probably like this:

 

Each JavaScript function has the prototype attribute, which references an object, which is a prototype object. The initialization of the prototype object is empty. We can customize any attributes and methods in it. These methods and attributes will be inherited by the object created by the constructor.

Now the problem is coming. What is the relationship between constructors, instances, and prototype objects?

Differences between constructors, instances, and prototype objects

An instance is created by a constructor. When an instance is created, it has the constructor attribute (pointing to the constructor) and the _ proto _ attribute (pointing to the prototype object ),

The constructor has a prototype attribute, which is a pointer to its prototype object.

The prototype object also has a pointer (constructor attribute) pointing to the constructor: Person. prototype. constructor = Person;

The instance can access the properties and methods defined on the prototype object.

Here, person1 and person2 are instances, and prototype is their prototype object.

Let's look at another example:

Copy the Code as follows:


<Script type = "text/javascript">
Function Animal (name) // accumulate Constructor
{
This. name = name; // Sets object attributes.
}

 

Animal. prototype. behavior = function () // Add the behavior method to the prototype of the base class Constructor
{
Alert ("this is a" + this. name );
}

Var Dog = new Animal ("dog"); // create a Dog object
Var Cat = new Animal ("cat"); // create a Cat object

Dog. behavior (); // call the behavior method directly through the Dog object
Cat. behavior (); // output "this is a cat"

Alert (Dog. behavior = Cat. behavior); // output true;
</Script>

 

The program running result shows that the methods defined on the prototype of the constructor can be directly called through the object, and the code is shared. (You can try removing the prototype attribute in Animal. prototype. behavior to see if it can run .) Here, the prototype property points to the Animal object.

Array object instance

Let's look at the instance of an array object. When we create the array1 object, the actual object model of array1 In the Javascript engine is as follows:

Copy the Code as follows:


Var array1 = [1, 2, 3];

 

The array1 object has a length attribute value of 3, but we can add an element to array1 using the following method:

Copy the Code as follows:


Array1.push (4 );


The push method comes from a method (Array. prototye. push () in which the _ proto _ member of array1 points to the object ()). It is precisely because all Array objects (created through []) contain a method object (Array. prototype), so that these array objects can use push, reverse and other methods.

 

Function object instance

Copy the Code as follows:


Function Base (){
This. id = "base"
}

 

 

Copy the Code as follows:


Var obj = new Base ();


What is the result of this Code? The object model we see in the Javascript engine is:

 

What does the new operator do? In fact, it is very easy to do three things.

Copy the Code as follows:


Var obj = {};
Obj. _ proto _ = Base. prototype;
Base. call (obj );

 

Prototype chain

Prototype chain: When a property or method is retrieved from an object, if the object itself does not have such an attribute or method, it will search for its associated prototype object. If prototype does not exist, it will search for the prototype associated with the prototype's predecessor Prototype. If there is no prototype, it will continue to search for prototype. the objects referenced by Prototype, and so on until Prototype. .... Prototype is undefined (the Prototype of the Object is undefined), thus forming the so-called "Prototype chain ".

 

Copy the Code as follows:


<Script type = "text/javascript">
Function Shape (){
This. name = "shape ";
This. toString = function (){
Return this. name;
}
}
Function TwoShape (){
This. name = "2 shape ";
}
Function Triangle (side, height ){
This. name = "Triangle ";
This. side = side;
This. height = height;
This. getArea = function (){
Return this. side * this. height/2;
}
}

 

TwoShape. prototype = new Shape ();
Triangle. prototype = new TwoShape ();
</Script>

 

Here, a new object is created with the constructor Shape (), and then its prototype is overwritten.

Copy the Code as follows:


<Script type = "text/javascript">
Function Shape (){
This. name = "shape ";
This. toString = function (){
Return this. name;
}
}
Function TwoShape (){
This. name = "2 shape ";
}
Function Triangle (side, height ){
This. name = "Triangle ";
This. side = side;
This. height = height;
This. getArea = function (){
Return this. side * this. height/2;
}
}

 

TwoShape. prototype = new Shape ();
Triangle. prototype = new TwoShape ();

TwoShape. prototype. constructor = TwoShape;
Triangle. prototype. constructor = Triangle;

Var my = new Triangle (5, 10 );
My. getArea ();
My. toString (); // Triangle
My. constructor; // Triangle (side, height)
</Script>

 

Prototype inheritance

Prototype inheritance: at the end of the prototype chain, it is the prototype Object pointed to by the prototype property of the Object constructor. This prototype object is the ancestor of all objects. This ancestor implements methods that are inherent to all objects such as toString. Prototypes of other built-in constructors, such as Function, Boolean, String, Date, and RegExp, are inherited from this ancestor, But they define their own attributes and methods, as a result, their children show the characteristics of their respective clan.

In ECMAScript, the method for implementing inheritance relies on the prototype chain.

Copy the Code as follows:


<Script type = "text/javascript">
Function Box () {// The inherited function is called a super-type (parent class, base class)
This. name = "Jack ";
}

 

Function Tree () {// The inherited function is called a child type (subclass, derived class)
This. age = 300;
}
// Inherit from the prototype chain and assign a value to the prototype attributes of the Child type
// New Box () transfers the information in the box structure and the information in the prototype to the Tree.
Tree. prototype = new Box (); // Tree inherits the Box and forms a chain through prototype

Var tree = new Tree ();
Alert (tree. name); // Jack is displayed.
</Script>

 

Prototype chain: although prototype chain is powerful, it can be used for inheritance, but it also has some problems. The most important problem is the prototype of the reference type. The prototype attributes that contain the reference type are shared by all instances. This is why the attributes are defined in the constructor rather than in the prototype object. When the prototype is used for inheritance, the prototype actually changes back to another type of instance. As a result, the original Instance property becomes the property of the prototype.

When creating a child-type instance, parameters cannot be passed to a super-Type constructor. In fact, it should be said that there is no way to pass parameters to super-type constructors without affecting all object instances. In addition, the prototype chain is rarely used in practice because the prototype contains reference type values.

Let's look at another example:

 

Copy the Code as follows:


<Script type = "text/javascript">
Function Person (name)
{
This. name = name; // Sets object attributes.
};

 

Person. prototype. company = "Microsoft"; // you can specify prototype attributes.
Person. prototype. SayHello = function () // prototype Method
{
Alert ("Hello, I'm" + this. name + "of" + this. company );
};

Var BillGates = new Person ("BillGates"); // create a person object
BillGates. SayHello (); // inherits the prototype content and outputs "Hello, I'm BillGates of Microsoft"

Var Jobs = new Person ("Jobs ");
Jobs. company = "Apple"; // you can set your own company attributes to conceal the original company attributes.
Jobs. SayHello = function ()
{
Alert ("Hi," + this. name + "like" + this. company );
};
Jobs. SayHello (); // overwrite attributes and methods, and output "Hi, Jobs like Apple"
BillGates. SayHello (); // the coverage of Jobs does not affect the prototype.
</Script>

 

Let's look at the following prototype chain example:

 

Copy the Code as follows:


<Script type = "text/javascript">
Function Year (){
This. value = 21;
}
Year. prototype = {
Method: function (){

 

}
};

Function Hi (){

};
// Set the prototype attribute of Hi to the Instance Object of Year
Hi. prototype = new Year ();
Hi. prototype. year = 'Hello world ';

Hi. prototype. constructor = Hi;

Var test = new Hi (); // create a new Hi instance

// Prototype chain
Test [Hi instance]
Hi. prototype [Year instance]
{Year: 'Hello world '}
Year. prototype
{Method :......};
Object. prototype
{ToString :...};

</Script>

 

In the preceding example, the test object inherits from Hi. prototype and Year. prototype. Therefore, the test object can access the prototype method of Year and the instance attribute value.

_ Ptoto _ attributes

The _ ptoto _ attribute (not supported by IE) is a pointer to the prototype object of the instance. It is used to point to the constructor, the prototype attribute of the constructor, you can access the attributes and methods in the prototype.

Object instances in Javascript are essentially composed of a series of attributes. Among these attributes, there is an internal invisible special attribute -- _ proto __, the value of this attribute points to the prototype of the object instance. An object instance has only one unique prototype.

 

Copy the Code as follows:


<Script type = "text/javascript">
Function Box () {// uppercase, representing the constructor
Box. prototype. name = "trigkit4"; // prototype attributes
Box. prototype. age = "21 ";
Box. prototype. run = function () // prototype Method
{
Return this. name + this. age + 'studying ';
}
}

 

Var box1 = new Box ();
Var box2 = new Box ();
Alert (box1.constructor); // constructor, which can be used to obtain the constructor itself,
// The role is to be located by the prototype pointer and then get the constructor itself
</Script>

 

_ Proto _ difference between properties and prototype Properties

Prototype is a unique attribute of a function object.
_ Proto _ is an implicit property of a Common Object. When new, it points to the object indicated by prototype;
_ Ptoto _ is actually the attribute of an object, while prototype is the attribute of the constructor. _ Ptoto _ can only be used in a learning or debugging environment.

Execution Process in prototype mode

1. first look for the attributes or methods in the constructor instance. If so, return immediately.
2. If the constructor instance does not exist, find it in its prototype object. If so, return immediately.

Prototype object

Copy the Code as follows:


<Script type = "text/javascript">
Function Box () {// uppercase, representing the constructor
Box. prototype. name = "trigkit4"; // prototype attributes
Box. prototype. age = "21 ";
Box. prototype. run = function () // prototype Method
{
Return this. name + this. age + 'studying ';
}
}

 

Var box1 = new Box ();
Alert (box1.name); // trigkit4, the value in the prototype
Box1.name = "Lee ";
Alert (box1.name); // Lee, on-going Principle

Var box2 = new Box ();
Alert (box2.name); // trigkit4, prototype value, not modified by box1
</Script>

 

Constructor

Copy the Code as follows:


<Script type = "text/javascript">
Function Box (){
This. name = "Bill ";
}

 

Box. prototype. name = "trigkit4"; // prototype attributes
Box. prototype. age = "21 ";
Box. prototype. run = function () // prototype Method
{
Return this. name + this. age + 'studying ';
}

Var box1 = new Box ();
Alert (box1.name); // Bill, the value in the prototype
Box1.name = "Lee ";
Alert (box1.name); // Lee, on-going Principle
</Script>

 

To sum up, sort out the following:

Copy the Code as follows:


<Script type = "text/javascript">
Function Person (){};

 

Person. prototype. name = "trigkit4 ";
Person. prototype. say = function (){
Alert ("alarm Hi ");
}

Var p1 = new Person (); // prototype is the prototype object of p1 and p2.
Var p2 = new Person (); // p2 is an instantiated object, which has a _ proto _ attribute inside, pointing to the prototype of Person

Console. log (p1.prototype); // undefined. This attribute is an object and cannot be accessed.
Console. log (Person. prototype); // Person
Console. log (Person. prototype. constructor); // The prototype object also has a pointer (constructor attribute) pointing to the constructor.
Console. log (p1. _ proto _); // This property is a pointer to the prototype object.
P1.say (); // The instance can access the attributes and methods defined on the prototype object.

</Script>

 

Factory Model

Copy the Code as follows:


Function createObject (name, age ){
Var obj = new Object ();
Obj. name = name;
Obj. age = age;
Return obj;
}

 

The factory mode solves the problem of a large number of repeated instantiated objects, but there is another problem, that is, it is impossible to figure out which object they actually belong.
The constructor not only solves the problem of repeated instantiation, but also solves the problem of object recognition.

The difference between the constructor method and the factory mode is:

1. Create Object (new Object () not displayed in the constructor method ());
2. directly assign attributes and methods to this object
3. No return Statement

When the constructor and the new Constructor () are used, the new Object () is executed in the background ();
In the function body, this indicates the new Object ().

1. You can use the 'hasownproperty () 'function to determine whether the attribute is in the constructor instance or in the prototype.
2. the constructor attribute is used to create a literal Object instead of an instance. The constructor is used to create a constructor.
Why Object? Because Box. prototype = {}; this method creates a new object.
Each time a function is created, its prototype will be created at the same time, and this object will automatically obtain the constructor attribute.
3. For instance methods and different instantiation methods, their method addresses are different and unique.
4. If it is a prototype method, then their addresses are shared

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.