JavaScript object-oriented Prototypes and inheritance _ js object-oriented

Source: Internet
Author: User
This article is translated from ScottAllenPrototypesandInheritanceinJavaScript, a Microsoft cool-man. This article gives a detailed analysis and explanation of Prototype and Prototype inheritance. It is one of the best works to understand JSOO. I. Preface

This article is translated from Microsoft's cool man Scott Allen Prototypes and Inheritance in JavaScript. This article gives a detailed analysis on what Prototype is and why Prototype can be used to implement Inheritance, it is one of the best works to understand js oo. If the translation is poor, I hope you can modify it.

Ii. Text
Object-oriented in JavaScript is different from other languages. It is best to forget the object-oriented concepts you are familiar with before learning. OO in JS is more powerful, more worth discussing (arguably), and more flexible.

1. Classes and objects
JS is an object-oriented language from the traditional perspective. Combine attributes and behaviors into an object. For example, array in JS is an object combined by attributes and methods (such as push, reverse, pop.

The Code is as follows:


Var myArray = [1, 2];
MyArray. push (3 );
MyArray. reverse ();
MyArray. pop ();
Var length = myArray. length;


Q: Where do these methods (such as push) come from? Some static languages (such as JAVA) use class to define the structure of an object. However, JS does not have a classless language, and no class called "Array" defines these methods for each array to inherit. Because JS is dynamic, we can add methods to objects as needed. For example, the following code defines an object, which represents the coordinates in a two-dimensional space and contains an add method.

The Code is as follows:


Var point = {
X: 10,
Y: 5,
Add: function (otherPoint)
{
This. x = otherPoint. x;
This. y = otherPoint. y;
}
};


We want each point object to have an add method. We also want all poin objects to share an add method without adding the add method to all point objects. This requires prototype to appear.

2. About Prototypes
Every object in JS has an implicit property (state) -- a reference to another object, called the prototype of the object. the array and point we created above also contain prototype references. Prototype reference is implicit, but it is implemented by ECMAScript. It allows us to obtain it using the _ proto _ attribute of the object (in Chrome. In terms of concept, we can consider the relationship between objects and prototype as shown in:

As a developer, we will use the Object. getPrototypeOf function to replace the _ proto _ attribute to view the prototype reference of the Object. At the time of writing this article, the Object. getPrototypeOf function is already supported in Chrome, firefox, and IE9. In the future, more browsers will support this feature, which is already one of ECMAScript standards. We can use the following code to prove that myArray and the point object we created previously reference two different prototype objects.

The Code is as follows:


Object. getPrototypeOf (point )! = Object. getPrototypeOf (myArray );



In the next part of the article, I will also use _ proto _, mainly because _ proto _ is intuitive in diagrams and sentences. But remember that this is not a standard. Object. getPrototypeOf is the recommended method for obtaining the Object prototype.

2.1 What makes Prototypes so special?

We already know that the push method of array comes from the prototype object of myArray. Is one of Chrome. We call Object. getPrototypeOf to obtain the prototype Object of myArray.

Figure 2

Note that the prototype object of myArray contains many methods, such as push, pop, and reverse, which we have used in the initial code. The prototype object is the only owner of the push method, but how is this method called through myArray?

The Code is as follows:


MyArray. push (3 );


To understand how it is implemented, the first step is to recognize that Protytype is not special at all. Prototype is an object. We can add methods and attributes to these objects, just like any other JS objects. However, Prototype is also a special object.

Prototype is special because of the following rules: When we notify JS that we want to call the push method on an object or read an attribute, the interpreter (runtime) first, find the method or attribute of the object. If the interpreter does not find this method (or attribute), it searches for each member in the prototype of the object along the _ proto _ reference. When we call the push method in myArray, JS does not find push in the myArray object, but the push method () is called in the prototype object of myArray ().

Figure 3

The behavior I described is essentially that the object inherits all the methods and attributes in its prototype. We do not need to use class in JS to implement this inheritance relationship. That is, a JS object inherits features from its prototype.

It also tells us that each array object can maintain its own state and members. If we need the length attribute of myArray, JS will find the length value from myArray instead of prototype. We can use this feature to "override" A method, that is, put the method to be overwritten (like push) into myArray's own object. In this way, the push method in prototype can be effectively hidden.

3. Share Prototype
The amazing thing about Prototype in JS is that multiple objects can reference the same prototype object. For example, we create two Arrays:

The Code is as follows:


Var myArray = [1, 2]; var yourArray = [4, 5, 6];


The two arrays share the same prototype object. The following code returns true.

The Code is as follows:


Object. getPrototypeOf (myArray) === Object. getPrototypeOf (yourArray );


If we call the push method in two arrays, JS will call the push in their common prototype.

Prototype objects give us this inheritance feature in JS, and they also allow us to share the implementation of the method. Prototype is also chained. In other words, if prototype is an object, the prototype object can also have a reference pointing to another prototype object. We can see that the _ proto _ attribute of prototype is a non-null value and also points to another prototype. when JS starts looking for member variables, such as the push method, it will check each object along the prototype reference until the object is found or reached the end of the chain. This chain method increases the flexibility of JS relay and sharing.

Next, you may ask: How do I set prototype reference for a custom object? For example, how do we add an add method to a prototype object for a previously created object point so that all point objects can inherit it? Before answering this question, let's take a look at the functions in JS.

4. About Funciton
Functions are also objects in JS. Functions have many important features in JS. We cannot list them one by one in this article. However, assigning a function to a variable or using a function as a parameter of another function is a basic method in today's JS programming.

We need to pay attention to the following: because a function is an object, it has reference to methods, attributes, and a prototype object. Let's discuss the meaning of the code below the idea:

The Code is as follows:


// This will return true:
Typeof (Array) = "function"
// And so will this:
Object. getPrototypeOf (Array) === Object. getPrototypeOf (function (){})
// And this, too:
Array. prototype! = Null


The first line of code proves that Array is a function in JS. Later we will see how to call the Array Function to create a new array object.

The second line of code proves that the Array object and function object reference the same prototype, just as all the array objects we saw earlier share a prototype.

The last line proves that the Array function has a prototype attribute. Never confuse the prototype attribute with the _ proto _ attribute. They have different purposes and objects.

The Code is as follows:


// True
Array. prototype = Object. getPrototypeOf (myArray)
// Also true
Array. prototype = Object. getPrototypeOf (yourArray );


We used the new knowledge to reproduce the previous image:

Figure 5

Now we want to create an array object. One of the methods is:

The Code is as follows:


// Create a new, empty object
Var o = {};
// Inherit from the same prototype as an array object
O. _ proto _ = Array. prototype;
// Now we can invoke any of the array methods...
O. push (3 );


Although the above Code looks good, the problem is that every JS Environment supports the _ proto _ attribute of the object. Fortunately, JS has a built-in standard mechanism to create a new object and set the _ proto _ attribute of the object. This is the "new" operator.

The Code is as follows:


Var o = new Array ();
O. push (3 );


The "new" operator has three important tasks in JS: First, it creates a new empty object. Next, it sets the _ proto _ attribute of the new object to point to the prototype attribute of the function to be called. Finally, execute the call function and point the "this" pointer to a new object. If we expand the above two lines of code, we will get the following code:

The Code is as follows:


Var o = {};
O. _ proto _ = Array. prototype;
Array. call (o );
O. push (3 );


The "call" method of the function allows you to call a function and specify the "this" in the function to point to the new object passed in. Of course, we also want to use the above method to create our own objects to realize Object Inheritance. This kind of function is a well-known constructor.

5. Constructor
Constructor is a common JS function object with two unique identifiers:

1. uppercase letters (easy to recognize ).

2. Join the new operator to construct a new object.

Array is a constructor-the Array Function is connected with new and capitalized. The Array Function in JS is built-in, but anyone can create their own constructor. In fact, it is time to create a constructor for the point object.

The Code is as follows:


Var Point = function (x, y ){
This. x = x;
This. y = y;
This. add = function (otherPoint ){
This. x = otherPoint. x;
This. y = otherPoint. y;
}
}
Var p1 = new Point (3, 4 );
Var p2 = new Point (8, 6 );
P1.add (p2 );


In the above Code, we use the new operator and the Point function to construct a point object. In the memory, you can think of the final result as the representation.

Figure 6

The problem is that the add method exists in each point object. Given our understanding of prototype, adding the add method to Point. prototype is a better choice (you do not have to copy the code of the add method to each object ). To achieve this goal, we need to make some modifications on the Point. prototype object.

The Code is as follows:


Var Point = function (x, y ){
This. x = x;
This. y = y;
}
Point. prototype. add = function (otherPoint ){
This. x = otherPoint. x;
This. y = otherPoint. y;
}
Var p1 = new Point (3, 4 );
Var p2 = new Point (8, 6 );
P1.add (p2 );


Okay! We have used prototype to implement inheritance in JS!

6. Summary
I hope you can use this article to get rid of prototype. Of course, this is just a powerful and flexible prototype entry. More prototype knowledge is expected to be explored and discovered by the reader.
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.