Improve javascript code with AOP

Aop is also called aspect-oriented programming. Students who have used spring must be very familiar with it. In js, AOP is a technical point that is seriously neglected. This article will use the following small examples to talk about AOP in js. Magical use in .

1. Prevent window.onload from being overwritten twice.
2. Non-intrusive statistical code.
3. Separate form request and validation.
4. Dynamically add parameters to ajax requests.
5. Chain of responsibility mode
.

First give the two "aspect" functions of before and after. As the name implies, it is to let a function execute before or after another function. The clever thing is that before or after can share this and arguments with the current function, so that There are so many places for us to play.

Handle window.onload being overwritten twice.

Some time ago, I saw someone in the QQ group asking a question, how can we not overwrite the previous window.onload function if we want to rewrite window.onload.

The most primitive solution must be to add your new code directly to the original window.onload.

The disadvantage of this is very obvious. It is the most invasive way to change the original function.

Another slightly better solution is to save the previous window.onload with an intermediate variable;

This adds a nasty intermediate variable, __onload, which costs some extra to manage.

Just imagine this scene. When people feel that the weather is cold, they naturally choose to wear a mink coat when they go out, instead of ripping off their skin and replacing it with mink. The benefits of dynamic decoration are reflected, not at all. Intrusion into the previous function.

Non-intrusive statistical code

The statistical code that has nothing to do with the logic itself needs to be hard-inserted into the function. I believe that many students who have reported it are very unhappy. For example, the following code is used to count a function that creates 1000 nodes on the user's computer. How much time will it take.

In the aop way, it is no longer necessary to make changes inside the function, and a general wrapper is defined first.

With just one line of code, you can add the function of counting time to any function.

Separate form request and validation

We often do some validation work before submitting the form to determine whether the form should be submitted normally. The worst way to write it is to put the validation logic in the send function.

A better way is to put all the validation rules into a set using the strategy mode, and return false or true to decide whether to pass the validation. In this way, the validation rules can be selected and replaced at will.

There is also a disadvantage in this way. The two requests of verification and sending request are coupled into one function. We use aop to separate them, and make validata a plug-in, which is truly plug-and-play. Just put the send function Change it to:

It is not difficult to see the code of Function.prototype.before at the front. We agreed that if the current function returns false, it will block the execution of the next function, so when validata returns false, it will not continue to execute send. And because The before function mentioned earlier can share this and arguments with the current function, so the value parameter can also be passed to the validata function smoothly.

Dynamically add parameters to ajax requests

In the first example, window.onload is post-decorated with after, and here is pre-decorated with before. Dynamically add some parameters before the ajax request.

We have encountered many cross-domain requests, and jsonp and iframe are both very common methods. In our project, we used the parameter retype=jsonp to indicate a jsonp request, and retype=iframe to indicate an iframe request. In addition, this There is no difference between the parameters of the two requests. Then you can use before to dynamically decorate the retype parameter.

First define a proxy function for an ajax request.

There is no logic processing and branching statements in this function, and it does not care whether it is a jsonp request or an iframe request. It is only responsible for sending data, and it is a good function with a single responsibility.

Next place a before decorator before sending the request.

Start sending requests:

Chain of Responsibility Pattern.

The typical application scenario of the chain of responsibility pattern in js is event bubbling. All child nodes and parent nodes are connected into a chain, and events are passed along this chain until a node can handle it. The chain of responsibility pattern is to eliminate The artifact of too many if else statements.

Take a recent requirement as an example. There is a file upload function, which provides four upload methods: control, html5, flash, and form upload. According to their priority and browser support, it is judged which upload method is currently selected. . Before I do the retrofit, its pseudocode looks like this:

Of course, the actual code is far more than that, including various control initialization, fault tolerance and so on. One day I need to shield the flash, it seems like a simple requirement, but the difficulty is actually similar to removing a wool blood vessel next to the heart.

How about trying the Chain of Responsibility pattern and see how much easier things get:

The first step is to rewrite the previous after function, so that when an object is returned, the transfer of the responsibility chain is blocked, and when null is returned, the request is continued.

Next, wrap the creation of each control in its own function to ensure that there is no logical intersection and mutual contamination.

And finally chain them together with a chain of responsibility:

It is foreseeable that one day I need to block the flash again. At that time, I only need to change this line of code. Change it to:

composition instead of inheritance

Many times when we design programs, we will encounter the problem of using composition or inheritance. Generally speaking, using composition is more flexible and lightweight. Take the previous file upload as an example.

I defined a superclass Upload, derived from 4 subclasses.
Plugin_Upload, Html5_Upload, Flash_Upload and Form_Upload.

Plugin_Upload will inherit the parent class, get most of the functions of Upload, and then customize some features of the control upload. For example, the other three upload methods start uploading after selecting the file. The control upload will go through a round before starting to upload. Document scanning.

The first approach is that Plugin_Upload inherits Upload, and then rewrites its start_upload method.

With a lighter composition, you can directly decorate the original start_upload function with the scanning function, without even needing to derive an additional subclass.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325974932&siteId=291194637