JavaScript in the prototype and inheritance detailed (graphic) _javascript skills

Source: Internet
Author: User

Forget all the object-oriented knowledge you learned before. Just consider the car situation here. Yes, it's the car.

Recently I was watching Hours of Le Mans, a popular tournament in France. The fastest car is called the Le Mans prototype car. These cars are made by the "Audi" or "Peugeot" vendors, but they are not the kind of cars you see on the street or on the freeway. They are made for the high-speed endurance races.

Manufacturers have invested huge sums of money in the development, design and manufacture of these prototypes, and engineers are always trying to make the project the ultimate. They experimented on alloys, biofuels, braking techniques, compound compositions and safety characteristics of tyres. Over time, some of these techniques have been repeatedly modified to move into the mainstream product line of the vehicle. Some of the techniques you're driving may be the first to appear on a car prototype.

You can also say that these mainstream vehicles inherit the technical prototype from the car.

Now we have the basics of discussing prototypes and inheritance issues in JavaScript. It's not like the classic inheritance pattern you know in C + +, Java, or C #, but it's just as powerful and potentially more flexible.

About objects and classes

JavaScript is all objects, which refers to objects in the traditional sense, that is, "a single entity that contains state and behavior." For example, an array in JavaScript is an object that contains several values and includes push, reverse, and pop methods.

var myarray = [1, 2];
Myarray.push (3);
Myarray.reverse ();
Myarray.pop ();
var length = Myarray.length;

Now the question is, where does this approach come from? The static language we mentioned earlier uses "class syntax" to define the structure of the object, but JavaScript is a language without "class syntax" and cannot define each array object with the syntax of the array "class". And because JavaScript is a dynamic language, we can place the method anywhere on the object, if we really need it. For example, the following code, in two-dimensional space, defines a point object to represent a point, and also defines an Add method.

var point = {
  x:10,
  y:5,
  add:function (otherpoint) {
    this.x = otherpoint.x;
    This.y + = Otherpoint.y;
  }
;

But the scalability of the above approach is not good. We need to make sure that each point object contains an Add method, and that all point objects share the implementation of the same Add method instead of adding each point object manually. This is where the prototype plays its part.

About prototypes

In JavaScript, each object maintains a hidden state-a reference to another object, also known as a prototype. The array we created earlier refers to a prototype object, as do the point objects we create ourselves. It says that the stereotype reference is hidden, but the implementation of ECMAScript (the official name of JavaScript) can be accessed through an object's __proto__ attribute (for example, Google browser) to this stereotype reference. Conceptually, we can treat an object as a relationship to a prototype, similar to the object represented in Figure 1.

Figure 1

Looking ahead, developers will be able to use the object.getprototypeof function, instead of the __proto__ attribute, to get the reference to the object prototype. You can already use the object.getprototypeof function in Google Chrome,firefox and IE9 browsers when writing this article. More browsers will implement this feature in the future because it is already part of the ECMAScript standard. We can use the following code to prove that the myarray and point objects we built refer to two different prototype objects.

    1. Object.getprototypeof (point)!= object.getprototypeof (myarray);

For the remainder of this article, I will cross-use the __proto__ and object.getprototypeof functions, mainly because __proto__ is easier to identify in graphs and sentences. The thing to keep in mind is that it's not standard, and the object.getprototypeof function is the recommended way to view the object's __proto__.

What makes a prototype so special?

We have not answered the question: Where does the method of push in an array come from? The answer is: It comes from the MyArray prototype object. Figure 2 is a screenshot of the script Debugger in the Chrome browser. We have called the Object.getprototypeof method to view the MyArray prototype object.

Figure 2

Note There are many methods in the MyArray prototype object, including the push, pop, and reverse methods that are invoked in the code example. Therefore, the prototype object does include a push method, but how does the MyArray method refer to it?

Myarray.push (3);

The first step in understanding how it works is to realize that the prototype is not special. Prototypes are just plain objects. You can add methods, attributes to the stereotype, and treat them like other JavaScript objects. However, the phrase "pig" in George Orwell's novel "Animal Farm"--all objects should be equal, but some objects (who follow the rules) are more equal than others.

The prototype objects in JavaScript are really special because they follow the following rules. When we tell JavaScript that we want to call an object's push method, or read the object's X property, the runtime looks at the object itself first. If the runtime cannot find what it wants, it will follow the __proto__ reference and object prototypes to find the member. When we called the MyArray push method, JavaScript did not find the push method on the MyArray object, but found it on the MyArray prototype object, so JavaScript called this method (see Figure 3).

Figure 3

The behavior described above refers to the fact that an object itself inherits any method or property on the prototype. JavaScript does not actually need to use class syntax to implement inheritance. Like a car that inherits the technology from a racing prototype, a JavaScript object can also inherit functionality from a prototype object.

Figure 3 also shows that each array object can also maintain its own state and members. When the MyArray length property is requested, JavaScript obtains the value of the length property in MyArray without reading the corresponding value in the prototype. We can "override" the push method by adding a push to the object. This effectively hides the push method implementation in the prototype.

Shared prototypes

The real magic of JavaScript-style primitives is how multiple objects maintain references to the same stereotype object. For example, if we create two arrays like this:

var myarray = [1, 2];
var yourarray = [4, 5, 6];

The two arrays will share the same prototype object, and the following code evaluates to true:

Object.getprototypeof (myarray) = = object.getprototypeof (Yourarray);

If we refer to the push method on two array objects, JavaScript will look for a shared push method on the prototype.

Figure 4

The prototype object in JavaScript provides the inheritance function, as well as the shared implementation of the method. Prototypes are also chain-type. In other words, because a prototype object is just an object, a prototype object can be maintained to a reference to another prototype object. If you re-examine Figure 2, you can see that the __proto__ property of the prototype is a Non-null value pointing to another prototype. When JavaScript looks for a member like the push method, it checks each object with the prototype reference chain until it finds the member, or arrives at the end of the prototype chain. The prototype chain opens up a flexible approach to inheritance and sharing.

The next question you might ask is: How do I set up the prototype references for those custom objects? For example, the point object used earlier, how can you add the Add method to a prototype object and inherit the method from multiple point objects? Before answering this question, we need to look at the function.

About functions

A function in JavaScript is also an object. Such a statement brings several important results, and we do not cover all the issues in this article. The ability to assign a function to a variable and to pass a function as a parameter to another function constitutes the basic paradigm of modern JavaScript programming expression.

What we need to be concerned about is that the function itself is an object, so the function can have its own method, attribute, and reference a prototype object. Let's discuss the meaning of the following code.

This returns true:
typeof (Array) = = = "function"
//Such an expression is also:
object.getprototypeof (array) = = Object.getprototypeof (function () {})
and/or such expressions are the same:
array.prototype!= NULL

The first line in the code proves that the array in JavaScript is a function. Later we'll see how to call the array function to create a new array object. The next line of code proves that the array object uses the same prototype as any other function object, just as we see the same prototype shared among the array objects. The last line of code proves that the Array function has a prototype property, and that the prototype attribute points to a valid object. This prototype attribute is very important.

Every function object in JavaScript has a prototype attribute. never confuse the __proto__ property of this prototype property. They do not use the same purpose, nor point to the same object.

Returns True
object.getprototypeof (Array)!= Array.prototype

ARRAY.__PROTO__ provides an array prototype – treat it as an object inherited by the array function.

The Array.protoype, however, provides a prototype object for all arrays. That is, it provides a prototype object like MyArray, and also contains methods that all arrays will inherit. We can write some code to prove the fact.

True
Array.prototype = = object.getprototypeof (myarray)
//also true
Array.prototype = = Object.getprototypeof (Yourarray);

We can also use this new knowledge to redraw the schematic before.

Figure 5

Based on the knowledge you know, imagine creating a new object and making the new object behave like an array. One way is to use the following code.

Create a new empty object
var o = {};
Inherits from the same prototype, an array object
o.__proto__ = Array.prototype;
Now we can call any method
of the array ... O.push (3);

While this code is interesting and works, the problem is that not every JavaScript environment supports writable __proto__ object attributes. Fortunately, JavaScript does have a standard mechanism for creating objects, requiring only one operator to create new objects and set __proto__ references to new objects-that is, the "new" operator.

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

The new operator in JavaScript has three basic tasks. First, it creates a new empty object. Next, it sets the __proto__ property of the new object to match the prototype property of the called function. Finally, the operator invokes the function, passing the new object as a "this" reference. If you want to extend the last two lines of code, it becomes the following:

var o = {};
o.__proto__ = Array.prototype;
Array.call (o);
O.push (3);

The call method of a function allows you to specify the object referenced by "This" within the function, when calling the function. Of course, the author of a function needs to implement such a function in this case. Once the author has created such a function, it can be called a constructor.

Constructors

Constructors are the same as ordinary functions, but have the following two special properties.

    1. Usually the first letter of the constructor is capitalized (making it easier to recognize the constructor).
    2. Constructors are usually combined with the new operator to construct the object.

An Array is an example of a constructor. The array function needs to be used with the new operator, and the first letter of the array is capitalized. JavaScript includes Array as a built-in function, and anyone can write their own constructors. In fact, we can finally write a constructor for the point object we created earlier.

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 the object with the X and Y attributes and an Add method. You can think of the final result as Figure 6.

Figure 6

The problem now is that we still have separate add methods in each of our point objects. Using the prototypes and inherited knowledge we have learned, we prefer to move the Add method of the point object from each point instance to the Point.prototype. To achieve the effect of inheriting the Add method, all we need to do is modify the Point.prototype object.

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);

Done! We just finished the prototype inheritance pattern in JavaScript!

Figure 7

Summarize

I hope this article will help you uncover the mystery of the JavaScript archetype concept. The first thing to see is how the prototype lets an object inherit functionality from other objects, and then see how to combine the new operator and constructor to build the object. What is mentioned here is just the first step to unlocking the power and flexibility of the object prototype. This article encourages you to discover new information about prototypes and JavaScript languages yourself.

At the same time, please drive carefully. You never know what the vehicles on the road will inherit from their prototypes (defective) technology.

Original link: Script Junkie translation: Bole online-Emger

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.