Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use refactoring in javascript to improve all aspects of code

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "how to use refactoring in javascript to improve all aspects of code". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Preface

Do front-end development for some time, during this period of time, for their own requirements, not only the project can be completed, the normal use of the function of this level. Also try to study how to write elegant code, better performance, more maintainable code, popular is refactoring. This article can be regarded as a small record of mine. I would like to share it here. This article mainly aims at the introduction, the example is also simple, goes deep into the complex example and so on, there are suitable examples to write and share later. If you have your own opinions on how to write elegant code, maintainable code, or have the strength of refactoring, you are welcome to comment.

With regard to refactoring, I am going to write a series of articles that will be updated from time to time, mainly for the following schemes: logical confusion refactoring, separated responsibility refactoring, adding extensible refactoring, simplifying the use of refactoring, code reuse refactoring. It will be interspersed with the following principles: single responsibility principle, least knowledge principle, open-closed principle. If you have any good ideas about refactoring, or if you have any good examples, you are welcome to leave comments and leave valuable suggestions.

two。 What is refactoring

First of all, refactoring is not rewriting. Refactoring roughly means to use a series of refactoring methods to change the internal structure of the project without affecting the functional use of the project. Improve the readability and maintainability of the project.

No matter what the project is, there is an iterative process from simple to complex. In this process, without affecting the use of the project, we need to constantly optimize the code to maintain or increase the readability and maintainability of the code. In this way, you can avoid the need for a lot of communication in team collaborative development. To join the development of the project.

3. Why refactoring

Wash the clothes when they are dirty, mend them when they are broken, and throw them away if they don't fit.

With the continuous increase of business requirements, changes, abandonment, the code of the project will inevitably have defects, which will affect the readability, maintainability and even the performance of the project. The purpose of refactoring is to solve these defects and ensure code quality and performance. But the premise is that it does not affect the use of the project.

As for the reasons for refactoring, I have summed up the following points.

The logical structure of the function is chaotic, or because there are no comments, it is difficult for even the original code writer to sort out the logic.

The function has no expansibility to speak of and cannot be handled flexibly when it encounters new changes.

Because of the strong coupling of objects or business logic, the code of business logic is huge and it is difficult to troubleshoot during maintenance.

There is too much repetition of code and no reusability.

As the technology evolves, the code may also need to be modified with new features.

With the deepening of learning, for the previous code, whether there is a better solution.

Because of the way the code is written, although the function is used normally, it consumes a lot of performance and needs to be optimized by a different scheme.

4. When to ReFactor

At the right time, in the right thing.

In my understanding, refactoring can be said to run through the development and maintenance cycle of the entire project, and can be regarded as a part of refactoring. Generally speaking, at any time in development, as long as you see that the code is awkward and stimulate obsessive-compulsive disorder, you can consider refactoring. Just refer to the following points before refactoring.

First of all, refactoring is something that takes time to do. It may take more time than previous development time.

Second, refactoring is to optimize the code, as long as it does not affect the use of the project.

*, the difficulty of refactoring varies, it may only be slightly changed, and it may be even more difficult than before.

Based on the above points, you need to evaluate whether to refactoring or not. For the indicators of evaluation, you can refer to the following points

Quantity: whether too much code needs to be refactored.

Quality: readability, maintainability, code logic complexity, etc., whether the impact on the quality of the code has reached an unbearable level.

Time: whether there is plenty of time for refactoring and testing.

Effect: if you refactored the code, what improvements have been made, such as improved code quality, improved performance, better support for subsequent functions, and so on.

5. How to reconstruct

Select a target and target it.

How to reconstruct, this is the specific situation, a specific analysis. It's like "Why ReFactor". If you find something wrong with the code, make improvements to the situation.

Refactoring is also about writing code, but it's not just about writing, it's about sorting out and optimizing. If writing code requires a process of learning-understanding-proficiency, then refactoring requires a process of learning-perception-breakthrough-proficiency.

In the case of refactoring, here are a few simple examples

5-1. Function has no expansibility.

As an example, in one of my libraries, one of the API

/ / detect the string / / checkType ('165226226326) / / result:false let checkType=function (str, type) {switch (type) {case' email': return / ^ [\ w -] + (\ .[\ w -] +) * @ [\ w -] + (\ .[\ w-] +) + $/ .test (str) Case 'mobile': return / ^ 1 [3 | 4 | 5 | 7 | 8] [0-9] {9} $/ .test (str); case' tel': return / ^ (0\ d {2pr 3} -\ d {7pr 8}) (-\ d {1pm 4})? $/ .test (str); case 'number': return / ^ [0-9] $/ .test (str) Case 'english': return / ^ [a-zA-Z] + $/ .test (str); case' text': return / ^\ w+$/.test (str); case 'chinese': return / ^ [\ u4E00 -\ u9FA5] + $/ .test (str); case' lower': return / ^ [Amurz] + $/ .test (str) Case 'upper': return / ^ [Amurz] + $/ .test (str); default: return true;}}

This API looks fine and can detect some commonly used data. But there are two problems.

But what if you want to add other rules? You have to add case to the function. Add a rule and modify it once! This violates the open-closed principle (open to extensions, closed to modifications). It also causes the entire API to become bloated and difficult to maintain.

Another problem is that, for example, page A needs to add an amount check, page B needs a date check, but the amount check is only needed on page A, and the date check is only needed on page B. If you keep adding case. It causes the A page to add the verification rules that are only needed on the B page, causing unnecessary overhead. The same goes for the B page.

The suggested way is to add an extended interface to the API

Let checkType= (function () {let rules= {email (str) {return / ^ [\ w -] + (\ .[\ w -] +) * @ [\ w -] + (\ .[\ w-] +) + $/ .test (str);}, mobile (str) {return / ^ 1 [3 | 4 | 5 | 7 | 8] [0-9] {9} $/ .test (str) }, tel (str) {return / ^ (0\ d {2pje 3} -\ d {7je 8}) (-\ d {1je 4})? $/ .test (str);}, number (str) {return / ^ [0-9] $/ .test (str) }, english (str) {return / ^ [a-zA-Z] + $/ .test (str);}, text (str) {return / ^\ w+$/.test (str);}, chinese (str) {return / ^ [\ u4E00 -\ u9FA5] + $/ .test (str) }, lower (str) {return / ^ [a murz] + $/ .test (str);}, upper (str) {return / ^ [Amurz] + $/ .test (str);}} / / expose interface return {/ / verify check (str, type) {return rules [type]? rules [type] (str): false;}, / / add rule addRule (type,fn) {rules [type] = fn;}}) () / / call method / / use the mobile verification rule console.log (checkType.check ('188170239 monetary verification mobile')); / / add the amount verification rule checkType.addRule ('money',function (str) {return / ^ [0-9] +. [0-9] {2})? $/ .test (str)}); / / use the amount verification rule console.log (checkType.check (' 18.36 amount verification money'))

The above code is a little more, but it doesn't take much effort to understand, and it's extensible.

The above improvement is actually improved by using the strategy pattern (encapsulating a series of algorithms so that the algorithm code and logic code can be independent of each other and will not affect the use of the algorithm). The concept of strategic pattern is a bit circuitous to understand, but if you look at the code, it should not.

Let's talk about a little bit here, functionally, to increase the expansibility of the function through refactoring, which is realized here. But if the checkType above is the API of an open source project, the way it is called before refactoring is: checkType ('165226226326). After refactoring, the invocation method is: checkType.check ('188170239 recording recorded phone'); or checkType.addRule ();. If the author of the open source project reconstructs in the above way, it may be a tragedy for the API developer checkType who used the open source project before, because as soon as the developer updates the version of the project, there will be a problem. Because the above refactoring is not backward compatible.

If it is to be backward compatible, it is not difficult. Just add a judgment.

Let checkType= (function () {let rules= {email (str) {return / ^ [\ w -] + (\ .[\ w -] +) * @ [\ w -] + (\ .[\ w-] +) + $/ .test (str);}, mobile (str) {return / ^ 1 [3 | 4 | 5 | 7 | 8] [0-9] {9} $/ .test (str) }, tel (str) {return / ^ (0\ d {2pje 3} -\ d {7je 8}) (-\ d {1je 4})? $/ .test (str);}, number (str) {return / ^ [0-9] $/ .test (str) }, english (str) {return / ^ [a-zA-Z] + $/ .test (str);}, text (str) {return / ^\ w+$/.test (str);}, chinese (str) {return / ^ [\ u4E00 -\ u9FA5] + $/ .test (str) }, lower (str) {return / ^ [a murz] + $/ .test (str);}, upper (str) {return / ^ [Amurz] + $/ .test (str);}} / / expose interface return function (str,type) {/ / extend rules if type is a function, otherwise verify data if (type.constructor===Function) {rules [str] = type;} else {return rules [type]? rules [type] (str): false;}}) () Console.log (checkType ('188170239)); checkType (' money',function (str) {return / ^ [0-9] + (. [0-9] {2})? $/ .test (str)}); / / use the amount verification rule console.log (checkType ('18.36 dollars))

This works well and is extensible, but for code cleanliness addicts, it's not elegant. Because checkType violates the principle of function singleness. Too much responsibility for a function can lead to immeasurable problems in the future, and the use of it can be confusing.

In the face of such a situation, personally, the way to understand is to keep the checkType without making any changes, add a new API to the project, such as checkTypOfString, and write the refactored code into the checkTypOfString. Guide developers to use less old checkType and more checkTypOfString in a variety of ways. In subsequent project iterations, checkType will be discarded at the appropriate time.

5-2. Function violates the principle of singleness

One consequence of a function violating the single principle is that it can lead to logical confusion. If a function takes on too much responsibility, try the principle of function singleness-- a function does only one thing.

The following example

/ / A batch of student information is currently entered, but the data are duplicated and need to be deduplicated. Then change the empty information into secrecy. Let students= [{id:1, name:' waiting', sex:' male', age:'',}, {id:2, name:' wandering', sex:' male', age:''}, {id:1, name:' waiting' Sex:'', age:''}, {id:3, name:' Hong Yan', sex:'', age:'20'}] Function handle (arr) {/ / Array deduplicates let _ arr= [], _ arrIds= []; for (let item0polii {for (let key in item) {if (item[ key] =') {item [key] = 'secrecy';}); return _ arr;} console.log (handle (students))

There is no problem with the running result, but think about it, if in the future, if you change the requirements, for example, there will be no duplicate records of student information, and the deduplicated function will be removed. In this way, the whole function will have to be changed. It also affects the following operation flow. It is equivalent to changing the demand, and the whole method is kneeling. The fire at the city gate affected the fish in the pond.

The following is constructed using a single principle

Let handle= {removeRepeat (arr) {/ / Array deduplicated let _ arr= [], _ arrIds= []; for (let item0polii {for (let key in item) {if (item.key] = ='') {item [key] = 'secrecy';}) Return arr;}}; students=handle.removeRepeat (students); students=handle.setInfo (students); console.log (students)

The result is the same, but the requirements are changed, such as no need to repeat, comment the code or just delete it. This is equivalent to separating the responsibilities of the function, and the responsibilities do not affect each other before. Removing that step in the middle will not affect the next step.

/ / students=handle.removeRepeat (students); students=handle.setInfo (students); console.log (students)

5-3. Optimization of function writing method

In this case, there is now a better way to implement previous functions without affecting their use. Replace the previous solution with a better solution.

For example, the following requirements, which were sent by a friend in the group, led to some discussions later. Give a 20180408000000 string that the formatDate function processes and returns 2018-04-0800: 00:00.

Previous solution

Let _ dete='20180408000000' function formatStr (str) {return str.replace (/ (\ d {4}) (\ d {2}) (\ d {2}) /, "2018-04-0800: 00:00"

Later, this solution was studied. This way is to replace and populate the data according to the position of x, which is not difficult to understand.

Let _ dete='20180408000000' function formatStr (str,type) {let _ type=type | | "xxxx-xx-xx xx:xx:xx"; for (let I = 0; I

< str.length; i++){ _type = _type.replace('x', str[i]); } return _type; } formatStr(_dete); result:"2018-04-08 00:00:00" 在之后的几天,在掘金一篇文章(那些优雅灵性的JS代码片段,感谢提供的宝贵方式)的评论里面发现更好的实现方式,下面根据上面的需求自己进行改造。 let _dete='20180408000000' function formatStr(str,type){ let i = 0,_type = type||"xxxx-xx-xx xx:xx:xx"; return _type .replace(/x/g, () =>

Str [iTunes +])} formatStr (_ dete); result: "2018-04-08 00:00:00"

5-4. Code reuse

The above examples are all from js. Let's talk about two examples that have a little bit to do with html-- vue data rendering.

In the following code, the payChannelEn2Cn addZero formatDateTime functions are all in the methods of vue. Attention, everyone.

The previous way of writing

Cash cheque draft Alipay WeChat Pay Bank transfer advance payment

The problem with writing this way is that, first of all, there is a lot of code, and the second is that if the project has 10 places to render data in this way, if the rendering requirements change. For example, if the value of bank transfer is changed from bank_trans to bank, it will have to be modified 10 times in the project. The cost of time is too high.

Later, I used the following writing method, which can be regarded as a small refactoring.

{{payChannelEn2Cn (cashType)}}

PayChannelEn2Cn function, output result

PayChannelEn2Cn (tag) {let _ obj = {'cash':' cash', 'check':' check', 'draft':' draft', 'zfb':' Alipay','WX _ pay': 'WeChat Pay', 'bank_trans':' bank transfer' 'pre_pay': 'prepayment'} Return _ OBJ [tag];}

Another example is the writing of timestamp turning time. The principle is the same, but the code is different. Here is the original code.

{{new Date (payTime). ToLocaleDateString (). Replace (/ g,'-')}} {{addZero (new Date (payTime). GetHours ())}: {addZero (new Date (payTime). GetMinutes ())}}: {addZero (new Date (payTime). GetSeconds ())}}

AddZero time zero filling function

Example:3- > 03 addZero (I) {if (I < 10) {I = "0" + I;} return I;}

The problem is the same as the above, so I won't say much here, just write the refactored code.

{{formatDateTime (payTime)}}

FormatDateTime function, formatting string

FormatDateTime (dateTime) {return `${new Date (payTime). ToLocaleDateString (). Replace (/\ / / g,'-')} ${this.addZero (new Date (payTime). GetHours ())}: ${this.addZero (new Date (payTime). GetMinutes ())}: ${this.addZero (new Date (payTime). GetSeconds ())}`;} "how to use refactoring in javascript to improve all aspects of code" is here. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report