Prototypes and inheritance in the "Go" javascript

Source: Internet
Author: User

Forget about all the object-oriented knowledge you learned before. The only consideration here is the situation of the car. Yes, that's the car.

Recently I was watching the Hours of Le Mans, a popular event in France. The fastest car is known as the Le Mans prototype car. These cars are made by "Audi" or "Peugeot" manufacturers, but they are not the kind of cars you see on the streets or on expressways. They are built for high-speed endurance events.

Manufacturers invest huge sums of money to develop, design and manufacture these prototypes, and engineers are always trying to get the project to the extreme. They conducted various experiments on alloys, biofuels, braking techniques, compound compositions and safety characteristics of tires. Over time, some of the techniques in these experiments have been repeatedly improved and subsequently entered into the mainstream product line of the vehicle. Some of the techniques you drive may be the first to debut on a car prototype.

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

By now, we have been discussing the basics of prototyping and inheritance issues in JavaScript. It's not like the classic inheritance pattern you know in C + +, Java, or C #, but it's equally powerful and potentially more flexible.

About objects and classes

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

12345 varmyArray = [1, 2];myArray.push(3);myArray.reverse();myArray.pop();varlength = myArray.length;

Now the question is, where does the push approach come from? The static languages we mentioned earlier use "class syntax" to define the structure of an object, but JavaScript is a language that does not have a "class syntax" and cannot be used to define each array object with the syntax of the array "class". And because JavaScript is a dynamic language, we can put the method anywhere on the object, if we really need to. For example, the following code, in a two-dimensional space, defines a point object to represent a point, and an Add method is defined.

12345678 var point = {    x : 10,    y : 5,    add: function(otherPoint) {        this.x += otherPoint.x;        this.y += otherPoint.y;    }};

But the above approach is not very scalable. 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 by hand. This is where the prototype plays its part.

About prototypes

In JavaScript, each object holds a hidden state-a reference to another object, also known as a prototype. The array we created earlier refers to a prototype object, and so is the point object we created ourselves. It says that prototype references are hidden, but there are implementations of ECMAScript (the official name of JavaScript) that can be accessed through an object's __proto__ property (such as Google Chrome) to this prototype reference. Conceptually, we can use the object as 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 a reference to the object's prototype. The object.getprototypeof function can already be used in Google Chrome,firefox and IE9 browsers when written in 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 our MyArray and point objects refer to two different prototype objects.

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

For the remainder of this article, I'll cross-use the __proto__ and object.getprototypeof functions, mainly because __proto__ is easier to identify in diagrams and sentences. Remember that it (__PROTO__) is not a standard, and the object.getprototypeof function is the recommended way to see the object's prototype.

What makes a prototype so special?

We haven't answered this question: Where does the method of push in the array come from? The answer is: it originates from the MyArray prototype object. Figure 2 is the screen of the Script Debugger in Chrome. We have called the Object.getprototypeof method to view the MyArray prototype object.

Figure 2

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

1 myArray.push(3);

The first step in understanding how it works is to realize that prototypes are not special. Prototypes are just ordinary objects. You can add methods, attributes, and treats to prototypes as if they were other JavaScript objects. However, the idea of "pig" in George Orwell's novel Animal Farm is that all objects should be equal, but some objects (who obey the rules) are more equal than others.

Prototype objects in JavaScript are really special because they obey the following rules. When we tell JavaScript that we want to invoke the push method of an object, or read the X property of an object, the runtime first looks at the object itself. If the runtime cannot find what it wants, it will follow the __proto__ reference and object prototypes to find the member. When we call MyArray's Push method, JavaScript does not find the push method on the MyArray object, but it finds it on the MyArray prototype object, and JavaScript calls 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. In JavaScript, you don't actually need to use class syntax to implement inheritance. Like a car that inherits the technology from a racing prototype, a JavaScript object can inherit functionality from a prototype object.

Figure 3 also shows that each array object can also maintain its own state and members. In the case of a request to get the length property of MyArray, JavaScript will take 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.

Share prototypes

The real magic of the JavaScript model is how multiple objects maintain a reference to the same prototype object. For example, if we create such a two array:

12 varmyArray = [1, 2];varyourArray = [4, 5, 6];

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

1 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 inheritance, and it implements the sharing of the method. Prototypes are also chain-linked. In other words, because the prototype object is just an object, a prototype object can maintain a reference to another prototype object. If you revisit 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 path for inheritance and sharing.

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

About functions

The functions in JavaScript are also objects. Such a statement brings several important results, and we will not cover all the issues in this article. In this, the ability to assign a function to a variable and to pass one function as an argument to another function constitutes the basic paradigm of modern JavaScript programming expressions.

What we need to focus on is that the function itself is the object, so the function can have its own methods, properties, and reference a prototype object. Let's discuss the meaning of the following code.

123456 // 这将返回 true:typeof(Array) === "function"// 这样的表达式也是:Object.getPrototypeOf(Array) === Object.getPrototypeOf(function() { })// 这样的表达式同样:Array.prototype != null

The first line in the code proves that the array in JavaScript is a function. We'll see later 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 between the array objects. The last line of code proves that the Array function has a prototype property, and this prototype property points to a valid object. This prototype attribute is very important.

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

12 // 返回 trueObject.getPrototypeOf(Array) != Array.prototype

ARRAY.__PROTO__ provides an array prototype – use 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 for an array object such as MyArray, and also contains methods that all arrays will inherit. We can write some code to prove the fact.

1234 // trueArray.prototype == Object.getPrototypeOf(myArray)// 也是 trueArray.prototype == Object.getPrototypeOf(yourArray);

We can also use this new knowledge to redraw the previous.

Figure 5

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

123456 // 创建一个新的空对象varo = {};// 继承自同一个原型,一个数组对象o.__proto__ = Array.prototype;// 现在我们可以调用数组的任何方法...o.push(3);

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

12 varo = newArray();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 properties of the called function. Finally, the operator invokes the function and passes the new object as the "this" reference. If you want to extend the last two lines of code, you will become the following:

1234 varo = {};o.__proto__ = Array.prototype;Array.call(o);o.push(3);

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

constructor function

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

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

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

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

Figure 6

The problem now is that we still have a separate Add method in each of our point objects. Using the knowledge we have learned about prototypes and inheritance, we would prefer to transfer 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.

1234567891011 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 have just completed the prototype inheritance pattern in JavaScript!

Figure 7

Summarize

I hope this article will help you uncover the mysteries of the JavaScript prototype concept. Beginning to see how the prototype allows an object to inherit functionality from other objects, and then see how to combine the new operator with the 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 prototyping and JavaScript language.

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

Prototypes and inheritance in the "Go" javascript

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.