In addition, this article is an introductory article. I have just started learning Javascript. I have a little experience, so I want to write an article like this. There will inevitably be errors in the article. Please feel free to comment and correct me
Complaining about Javascript
When I come into contact with Javascript for the first time, this language will indeed make many regular soldiers feel a lot of discomfort. This discomfort comes from the simplicity and imprecision of Javascript's grammar. This discomfort also comes from the sad language of Javascript. Name, I'm thinking that the Javascript designer at Netscape must have had a wet brain the day he named it. Javascript has suffered so many unfair injustices over the years. People think it is an appendage of Java, a WEB toy language. That's why some people are disdainful of Javascript and think that Javascript is not a real language, but they are really wrong. Javascript is not only a language, it is a real language, but it is also a landmark language. It has created many new programming models, prototype inheritance, closure (Author's note: closure is not the first creation of JS, it should be Scheme was the first, prototypal inheritance and dynamic objects were the first of the self language. The first of Javascript was not exciting. Thank you for your correction.) It had a huge impact on subsequent dynamic languages. As the most popular language today (no one), you can understand it by looking at the most submitted language types on git. With the debut of HTML5, browsers will show their talents on personal computers. When there is a trend of replacing OS, Javascript will be the only real language on browsers, just like C is to unix/linux and java is. For JVM, Cobol is for MainFrame, we also need to seriously understand and examine this language again. In addition, the official name of Javascript is: ECMAScript. This name is obviously much more handsome than Javascript!
Getting back to business, let’s get to the topic - object-oriented programming in Javascript. To talk about object-oriented programming in Javascript, the first step we need to do is to forget the object-oriented programming we have learned. Learning Javascript's object-oriented thinking using traditional C or Java object-oriented thinking will bring you a lot of confusion. Let us forget what we have learned first and start learning this special object-oriented programming from scratch. Since it is OO programming, how do we understand OO programming? I remember that I used to learn C, but I didn’t get started after learning it for a long time. Later, I was fortunate enough to read the masterpiece "Inside The C Object Model", and it suddenly became enlightened. Therefore, this article will also use objects. A model approach to explore OO programming in Javascript. Because of the particularity of the Javascript object model, Javascript inheritance is very different from traditional inheritance. At the same time, because there are no classes in Javascript, this means that there are no extends or implementations in Javascript. So how does Javascript implement OO programming? Okay, let's get started and take a tour in the OO world of Javascript
First, we need to take a look at how Javascript defines an object. The following is one of our object definitions:
var o = { };
You can also define an object like this
function f() { }
Yes, you read that right, in Javascript, functions are also objects.
Of course
var array1= [ 1, 2,3];
An array is also an object.
For other descriptions of basic concepts of objects, please refer to Chen Hao's "Javascript Object-Oriented Programming" article.
The objects are all there, but the only thing missing is class, because there is no class keyword in Javascript. After all, there is also function. The existence of function allows us to define classes in a flexible way. Before expanding this topic, we also You need to understand the most important attribute of a Javascript object, the __proto__ member.
__proto__ member
Strictly speaking, this member should not be called this name. __proto__ is the name in Firefox, and __proto__ can only be accessed in the Firefox browser. As an object, when you access one of its members or methods, if there is no such method or member in this object, the Javascript engine will access another object pointed to by the __proto__ member of this object, and Search for the specified method or member in that object. If it cannot be found, it will continue to search recursively through the object pointed to by the __proto__ member of that object until the end of the linked list.
Okay, let’s give an example.
For example, the array object array1 defined above. When we create the object array1, the actual object model of array1 in the Javascript engine is as follows:
The array1 object has a length attribute value of 3, but we can use the following method to set the length attribute for array1 Add elements:
array1.push(4);
The push method comes from a method (Array.prototye.push()) pointed to by the __proto__ member of array1. It is precisely because all array objects (created through []) contain a __proto__ member that points to the same object (Array.prototype) with push, reverse and other methods that these array objects can use push, reverse and other methods.
Then the __proto__ attribute is equivalent to the "has a" relationship in object-oriented. In this case, as long as we have a template object such as the Array.prototype object, and then put other objects __proto_ If the _ attribute points to this object, an inheritance pattern is completed. good! We can definitely do this. But don't be too happy. This attribute is only valid in FireFox. Although other browsers also have attributes, they cannot be accessed through __proto__. They can only be accessed through the getPrototypeOf method, and this attribute is read-only. It seems that it is not easy for us to implement inheritance in Javascript.
Function object prototype member
First, let’s look at the definition of function prototype member,
When a function object is created, it is given a prototype member which is an object containing a constructor member which is a reference to the function object
When a function object is created, the function object has a prototype member. This member is an object. This object contains a constructor member. This constructor member will Points to this function object.
For example:
function Base() {
this.id = "base"
}
The function object Base has a prototype member. Regarding the constructor, it is actually the Base function object itself. Why do we call this type of function What about the constructor? The reason is because such functions are designed to be used with the new operator. In order to distinguish it from general function objects, the first letters of such functions are generally capitalized. The main function of a constructor is to create a class of similar objects.
The object model of the Javascript engine for the above code is like this
new operator With the above basic concepts After the introduction, by adding the new operator, we can create objects using the traditional object-oriented class new method. In Javascript, we call this method Pseudoclassical.
Based on the above example, we execute the following code
var obj = new Base();
What is the result of this code? The object model we see in the Javascript engine is:
What exactly does the new operator do? It’s actually very simple, just do it. Three things.
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
In the first line, we create an empty object obj
In the second line, we change the __proto_ of this empty object The _ member points to the Base function object prototype member object
In the third line, we replace the this pointer of the Base function object with obj, and then call the Base function, so we assign an id member variable to the obj object. This member The value of the variable is "base". For the usage of the call function, please refer to Chen Hao's "Javascript Object-Oriented Programming" article
What will be the effect if we add some functions to the Base.prototype object?
For example, the code is as follows:
Base.prototype.toString = function( ) {
return this.id;
}
Then when we use new to create a new object, according to the characteristics of __proto__, the toString method can also create new objects method is accessed. So we see:
In the constructor, we set the member variables of the 'class' (for example: id in the example), and in the constructor object prototype, we set the public methods of the 'class'. Therefore, the effects of classes and class instantiation are simulated through function objects, Javascript's unique __proto__ and prototype members, and the new operator.
Pseudoclassical inheritance
We simulate classes, so how should inheritance be done? It's actually very simple, we just need to point the prototype of the constructor to the parent class. For example, we design a Derive class. As follows
function Derive(id) {
this. id = id;
}
Derive.prototype = new Base();
Derive.prototype.test = function(id){
return this.id === id;
}
var newObj = new Derive("derive");
What does the object model look like after this code is executed? According to the previous derivation, it should be the following object model
In this way, our newObj also inherits the toString method of the base class Base and has its own member id. I leave it to you to learn how this object model is derived. Referring to the previous description, it should not be difficult to derive this object model.
Pseudoclassical inheritance will make students who have studied C/Java feel a little bit more comfortable, especially the new keyword, which is very familiar when you see it. However, although the two are similar, their mechanisms are completely different. Of course, no matter what kind of inheritance, you can't do without the __proto__ member.
Prototypal inheritance This is another inheritance method of Javascript. This inheritance is the create function in the previous article "Javascript Object-Oriented Programming" by Chen Hao. It is a pity that this It is the standard of ECMAScript V5. The browsers that support V5 currently appear to be IE9, the latest version of Chrome and Firefox. Although it seems a lot, as China is the hardest hit area of IE6, I suggest that you avoid using the create function. Fortunately, before there was a create function, Javascript users had already designed something equivalent to this function. For example: let's look at Douglas Crockford's object function.
function object(old) {
function F() {} ;
F.prototype = old;
return new F();
}
var newObj = object(oldObject);
For example, the following code segment
var base ={
id: "base",
toString:function(){
return this.id;
}
};
var derive = object(base);
The object model after the execution of the above function is:
How to form such an object model, the principle is also very simple, just expand the object function, you can draw this model, how The picture is left to the reader to draw.
This type of inheritance is called prototypal inheritance. Relatively speaking, it is simpler and more convenient than inheriting from Pseudoclassical. It is for this reason that ECMAScript V5 added the create function so that developers can quickly implement prototype inheritance.
The above two inheritance methods are the most commonly used inheritance methods in Javascript. Through the explanation of this article, you should have some 'principle' level understanding of OO programming in Javascript
Reference:
"Prototypes and Inheritance in JavaScript Prototypes and Inheritance in JavaScript"Advance Javascript (Douglas Crockford’s video must be watched) Off-topic:
After web2.0, web applications have developed rapidly. Now with the release of HTML5, browse The function of the browser has been greatly enhanced. I feel that Browser is far from being as simple as a Browser. I remember the father of C once said this about JAVA. JAVA is not cross-platform. JAVA itself is a platform. Today's Browser is itself a platform. Fortunately, this platform is based on standards. If the Browser is a platform, due to the limitations of the Browser security sandbox, the resources of the personal computer are rarely used. Does it feel like the Browser is an NC (Network Computer)? We have actually returned to the idea originally proposed by Sun. Is Sun too powerful?