The exclamation is to relieve the serious atmosphere and lead to the topic we are going to talk about today, "javascript object-oriented programming". Next, we will focus on several major keywords of object-oriented: encapsulation, inheritance, polymorphism.
Encapsulation: In the mode of creating objects in JavaScript, I personally think that closure is the real encapsulation, so first let’s briefly introduce closures, look at the following example:
Does it look familiar? That's right, this is actually a simple closure application. A brief explanation: the variables defined in the function myInfo above are accessible in its embedded function showInfo (this is easy to understand), but when we assign the return reference of this embedded function to a variable oldFish, this At this time, the function showInfo is called outside the body of the myInfo function, but the variables defined in the function body can also be accessed. oh yeah!
Let’s summarize the principle of closure: functions run in the scope where they are defined rather than the scope where they are called. In fact, returning an inline function is also the most common way to create a closure!
If you feel that the above explanation is too abstract, then let’s reshape the above function together to see if it is more hierarchical:
The coding style in the above example is relatively common in ext yui, with public and private distinctions clear at a glance. Through closures, we can easily hide some things that we do not want to be directly accessed from the outside. If you want to access the variables defined within the function, you can only access them through specific methods. Direct access from the outside is access. I couldn’t find it, it was quite tiring to write, so I finally came back to it after a while. Encapsulation, isn’t it just to hide things that you don’t want others to see? Haha...
If the above example is converted into JQ style, it should be written as the following example. This kind of encapsulation mode belongs to the open door mode, and the variables defined in it can be accessed externally (in the following example, if you Instantiate an object first, and then access the object's name or age attributes outside the function. Of course, in this mode, we can set some "hidden rules" to let team development members understand which variables are private. , usually we artificially add an underscore "_" before private variables and methods to mark a warning signal! Thus achieving "encapsulation"!
Some people may ask, which mode is better? How do you say this? Both methods have advantages and disadvantages, so use them together! In short, the principle is that if something cannot be directly accessed by external objects, use a closure to encapsulate it. The four words "Definitely Definitely" are very profound, and only through continuous practice can you realize the true meaning!
Inheritance: When mentioning this, I would like to add one more thing by the way: a shortcoming of closure encapsulation is not conducive to the derivation of subclasses, so closures are risky, and encapsulation needs to be cautious! For the sake of intuition, the way to create objects in the following example adopts the "open door" mode.
Inheritance in JavaScript is generally divided into three ways: "class inheritance", "prototype inheritance", and "meta-class". The following is a brief introduction to the principles of the three types of inheritance methods.
A. Class inheritance: This is the inheritance method commonly used in mainstream frameworks. See the following example:
The getName method is not defined in the above subclass Fish, but the instance object ioldFish of the subclass Fish still calls this method. This is because the subclass Fish inherits the getName method defined in the superclass Name. To explain, the prototype of the subclass Fish here points to an instance of the super class. Although the getName method is not declared in the subclass Fish, according to the principle of the prototype chain, the upper-level object pointed by the prototype will be searched to see if there is such a method. , if the method is not found, the original prototype object will be searched. This is actually the principle of inheritance. Here is a special explanation, Fish.prototype.constructor = Fish;, because the prototype of the default subclass should point to itself, but the prototype was pointed to the instance object of the super class before, so it needs to be set back here. Of course, the relevant code can be organized through a function to disguise extend. I will not elaborate here. You can pay attention to my next blog post...
B. Prototypal inheritance is better than class in terms of memory performance. inherit.
Obviously, the core of prototypal inheritance is the clone function, which is also the principle of the prototype chain. The difference is that it directly clones the super class. In this case, the subclass inherits all the attributes and methods of the super class. In particular, this type of inheritance There is no need to create a constructor, you only need to create an object word variable, define the corresponding properties and methods, and then in the subclass, you only need to refer to the properties and methods through the dot "." symbol.
C. Doped classes: Encapsulate some common and versatile methods into a function, and then assign them to the classes that use these methods through the following function. You can also selectively pass the required methods for different classes.
Polymorphism: Personally, I think this is relatively abstract and difficult to explain in words, so I will briefly explain it from the two aspects of overloading and overwriting.
Overloading: In the above example, the agument function initially takes two parameters, but in subsequent calls, agument(Fish,Name,"sayLove") can also take in any number of parameters. Overloading of javascript, It is implemented by the user in the function by manipulating the arguments attribute.
Override: This is very simple. If the method defined in the subclass has the same name as the method inherited from the superclass, this method will be overwritten (this is not overriding the method in the superclass, please note). Here is No more cumbersome!
Finally, let’s focus on this and execution context. In the previous encapsulation example, this represents the instantiation object itself of the class where this is located, but it is not the same. For example, it is defined through HTML attributes. Event handling code, see the following code:
Up In the example, after clicking the button, the properties of the instance object are not displayed in the pop-up box. This is because the execution context of this has changed. The context it is in now should be the input HTML tag, but the tag does not have the getName attribute. , so naturally the attribute value of this attribute cannot be output! From this example, we can easily see that the execution context is determined during execution and can change at any time.
Of course you can remove the code I commented out above and change the execution context of this through call to obtain the getName method. The apply method can also realize the function of changing the execution context, but a more beautiful implementation method bind was found in the prototype framework. Let’s take a look at the implementation of this method. I have to admire the greatness of our ancestors...
Function.prototype.bind = function(obj) {
var method = this,
temp = function() {
return method.apply(obj, arguments);
} ;
}
I believe that if you can understand it clearly, you can already rely on these knowledge points to write a simple script framework. Practice more and I believe you will be able to upgrade to a master in the near future. Got it! If you don’t understand it, don’t worry. Object-oriented is a bit abstract in nature. If you practice more, you should be OK. Come on...
Let’s write this article for now. In the next article, we can discuss it with you, javascript The design pattern, please stay tuned.