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

What is the common anti-pattern in JavaScript

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article focuses on "what are the common anti-patterns in JavaScript". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what are the common anti-patterns in JavaScript?"

Hard coding

Hard-coded (Hard-Coding) strings, numbers, dates... Everything that can be written to death will be written to death. This is a well-known anti-pattern, but also the most widely used anti-pattern. Probably the most typical hard-coding is platform-related code (Platform-Related), which refers to code that works only on a specific machine or environment, either on your machine or only on Windows.

For example, writing the script path / Users/harttle/bin/fis3 in npm script may be because it is very difficult to install once, it may be to avoid repeated installation, or it may simply be because it works. In any case, this will cause all your colleagues to come to you and ask, "Why am I wrong here?" The solution is to put it into dependency management, and if there is a specific version requirement, you can use package-lock, if you are not sure, you can regard it as an external dependency and put it in the local configuration file and remove it from version control (such as Git).

For example, write the special folder / tmp, ~ / .cache, or the path separator\ or / in the cli tool. Such strings can generally be obtained through Node.js built-in modules (or other runtime API), such as using os.homedir, os.tmpdir, path.sep, and so on.

Duplicate code

Repetitive code (Duplication) is particularly common in business code and is almost always intended to maintain the stability of the business. For example: you need a beautiful search box in page A, and there happens to be one in page B. At this point, the programmer is faced with a difficult choice (if you will feel a little uneasy if you copy it directly):

Make a copy of B and change it to what A wants.

Restructure the search box in B to Cline B and A to refer to this code.

Due to the lack of time, I want to get off work early, or I have to take responsibility for correcting B (PM: let you do A Why is B broken? Answer this question is more complicated, skip here first), after some thinking, decided to take option 2.

At this point, the whole story goes naturally and smoothly, which is probably why repetitive code is widely used. There are several points to be questioned in this story:

B is so easy to change, which shows that the author of B does not consider reuse. You should not reuse B's code at this time unless you decide to take over to maintain it.

The responsibility for correcting B is not just for programmers: did the author of B write tests, and did testers return to the test B page?

The shortage of time does not necessarily lead to the emergence of anti-patterns, which can not be used as a reason to convince yourself. There is also an elegant implementation of short-term solutions.

The solution is to extract the code from B to redevelop the search box component C and use it on the A page. At the same time, it is available to future partners, including urging the authors of B to migrate to C unified maintenance.

Fake AMD

Modularization originally means that each function of the software is separated into independent modules, and each module contains a complete subdivision function. In JavaScript, it refers to a reusable unit of code that cuts a script into separate contexts.

Since JavaScript started as a page script, there are many syntax that refers to global scope, as well as many practices based on global variables. For example, $of jQuery, window provided by BOM, omitting var to define variables, and so on. AMD is an earlier modular specification in the JavaScript community. This is a gentleman's agreement, and that's where the problem lies. There are countless ways to write fake AMD modules:

There is no return value. Yeah, all you want is side effects.

Require directly after define. Yes, all we want is to execute it immediately.

Have side effects. Modify window or other shared variables, such as the static properties of other modules.

Concurrency problem. Unknown dependencies can easily lead to concurrency problems.

The impact of global side effects is exactly the same as that of global variables, with almost all the disadvantages of global variables: the execution logic is not easy to understand; implicit coupling relationships; and it is difficult to write tests. Here is a concrete example:

/ / file: login.js

Define ('login', function () {

Fetch ('/ account/login') .then (x = > {

Window.login = true

})

})

Require (['login'])

This AMD module is no different from writing it directly in one, and is more uncontrollable, to be exact (the requirejs implementation is asynchronous). It also cannot be used by other modules (for example, to log out and log in again), because it does not return any interfaces. In addition, this module has a concurrency problem (Race Condition): use window.login to determine whether the login is unreliable.

The solution is to abstract it into a module, and its execution is controlled by the outside and the login result is obtained. In a well-modularized project, all states are eventually generated by the APP entry, and the shared states between modules are extracted to the nearest public superior.

Define (function () {

Return fetch ('/ account/login')

.then (() = > true)

.catch (e = > {)

Console.error (e)

Return false

}

})

Annotation expansion

The original intention of comments is to give readers a better understanding of the intent of the code, but in practice it may be just the opposite. Just give an example of life:

/ / determine that the version of Baidu is greater than 15.

If (navigator.userAgent.match (/ Chrome: (\ d +)) [1] < 15) {

/ /...

}

Haha when you read this paragraph, I believe the above comments have successfully consumed your time. It may be incredible if you see such comments for the first time, but most comments in real projects are in this state. Because maintenance code does not always remember to maintain comments, and there is usually more than one person who maintains the code. The sequelae of C language courses are not only variable naming, "often write notes" is also a very bad teaching.

The solution is to replace comments with clear logic. The rewritten code for the above example is as follows:

If (isHttpsSupported ()) {

/ / avoid adding comments by function extraction + naming

}

Function isHttpsSupported () {

Return navigator.userAgent.match (/ Chrome: (\ d +)) [1] < 15

}

Function volume expansion

It is generally believed that the expansion of the function body and global variables are the sequelae of the algorithm class. But the scenarios of complex business and algorithms are indeed different, and the former has more concepts and operations to explain and sort out. The most effective means of sorting out business logic are variable naming and method extraction (with corresponding closures or objects, of course).

But in real business maintenance, it is not easy to be rational. When you add business logic to the same file dozens of times, your function will be as smelly and long as a lazy foot-binding cloth:

Function submitForm () {

Var username = $('form input#username') .val ()

If (username = = 'harttle') {

Username = 'God'

} else {

Username = 'Mortal'

If ($('form input#words'). Val (). IndexOf (' harttle')) {

Username = 'prophet'

}

}

$('form input#username') .val (username)

$('form') .submit ()

}

This is just an example, more than a dozen lines are far from being "smelly and long". But you can already see that changes for a variety of purposes make submitForm () more than just submitting a form. One possible refactoring scenario is as follows:

Function submitForm () {

Normalize ()

$('form') .submit ()

}

Function normalize () {

Var username = parseUsername (

$('form input#username') .val ()

$('form input#words') .val ()

)

$('form input#username') .val (username)

}

Function parseUsername (username, words)

If (username = = 'harttle') {

Return 'God'

}

Return words.indexOf ('harttle')? 'prophet': 'Mortal'

}

In the refactored version, we separate the original input parsing, data normalization and other operations into different functions, which not only make submitForm () easier to understand, but also make it more convenient to further expand the business. For example, the input#password field is also checked in the normalize () method, such as adding a parseWords () method to parse the input#words field, and so on.

At this point, I believe that you have a deeper understanding of "what are the common anti-patterns in JavaScript?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

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