Click "Cloud Recommendations" with one click, get official recommended high-quality content, and learn technology without getting lost!
Readable code can greatly improve development efficiency. During development, a large part of the time is spent reading code. Readable code, easy to understand and easy to change. Conversely, unreadable code is bad to read and error-prone to change.
Here is a piece of unreadable code:
const user = ...
const foo = (cb) => ...
const bar = (list, cb) => ...
const other = (list1, list2) => ...
if(user ? user.isAdmin : ((user.permission && user.permission.view) ? user.permission.view === true : false)) {
foo((res) => {
if(res && res.ok && res.list && res.list.length > 0) {
bar(res.list, (res2) => {
if(res2 && res2.ok && res2.list && res2.list.length > 0) {
other(res.list, res2.list)
}
})
}
})
}
The above code has these problems:
- The name of the function does not match the function.
- if conditions are too complex and deeply nested.
- Callback functions are deeply nested.
Change the above code into readable code:
const user = ...
const fetchChannel = () => ...
const fetchArticle = (list) => ...
const render = (channelList, articleList) => ...
const hasViewPermission = user.isAdmin || user.permission?.view
if(!hasViewPermission) {
return
}
const { ok, list: channelList} = await fetchChannel()
if (!(ok && channelList?.length > 0)) {
return
}
const { ok: fetchArticleOk, articleList } = await fetchArticle(channelList)
if (!(fetchArticleOk && articleList.length > 0)) {
return
}
render(channelList, articleList)
In summary, readable code mainly has the following characteristics:
- Consistent code style.
- Reasonable naming.
- necessary comments.
- No large files.
- No deeply nested code.
How to write readable code?
Write readable code that meets the characteristics mentioned above.
1. Consistent code style
Consistent code style means: spaces, indentation, naming style (camel case, underscore, etc.) are consistent throughout the project. Consistent code style that looks neat and reduces understanding costs. In a project, it doesn't matter what code style you use. It is important that the style is consistent.
The more famous code styles in the front-end industry are: Airbnb JavaScript Style Guide and JavaScript Standard Style . If you don't want to toss, you can use JavaScript Standard Style . Features of JavaScript Standard Style:
No configuration is required. The most convenient way to unify the code style in history, easy to have.
Automatic code formatting. Just run standard --fix
and say goodbye to dirty code.
Spot stylistic and procedural issues ahead of time. Save time by reducing the iterative modification process during code review.
After determining the code style, you can use the inspection tool ESLint to ensure the uniformity of the code style. Before each code submission, do a check, you can use the tool: husky . For large projects, checking the entire project is too slow. Use lint-staged to check only this changed file.
2. Reasonable naming
There are only two hard things in Computer Science: cache invalidation and naming things. --Phil Karlton
A good naming is "see the name and know the meaning". Specifically, good naming has the following characteristics:
Straightforward, meaningful
Good naming is easy to understand, that is, straightforward and meaningful. For example: fetchUserInfo
.
Recommended: Palace Nomenclature
Extract the key features of the target object to name.
Recommended naming tool: CODELF . It helps you search Github, GitLab and other sites for different names of what you want to find.
Be careful not to misspell words in the name. Recommended word spell checker: Code Spell Checker .
follows industry practice
Good naming should also follow industry conventions. For example: the industry convention id is named as a unique identifier, do not use identifier. i, j, k are used to name the loop count variable.
conforms to code style
Good naming should match the code style of the current project. Such as: hump style and so on.
Bad naming has the following characteristics:
meaningless name
Meaningless names like: foo, bar, var1, fun1.
too abstract name
Too abstract names, such as: data, res, temp, tools.
will have ambiguous abbreviations
There will be ambiguous abbreviations, such as: mod. You may not be able to confirm whether it is mode or module.
Unnecessary context information
// bad
function async getUserName (userId) {
const userName = await fetchUser(userId)
return userName
}
// good
function async getUserName (id) {
const name = await fetchUser(id)
return name
}
too long name
The names are too long and not easy to understand. Such as: fetchGraintYoungestBoyName. Optimization method: Omit unimportant content. If changed to: fetchBoyName.
3. Necessary Notes
Comments are explanations and descriptions of code. Good code is self explanatory. For uncomplicated code, no comments are required. If you write a comment that just explains what the code does, it will not only waste the reader's time, but also mislead the reader (when the comment and the code function are inconsistent).
Scenarios that need to write comments:
- When the code itself does not clearly articulate the author's intent.
- The logic is more complicated.
4. No large files
Large file refers to a file with a large number of lines of code (more than 1,000 lines). Large files, meaning the code does a lot of stuff, it's hard to keep track of what's going on.
Large files can be found using the max-lines rule in ESLine.
Optimization solution: Split large files into several small files by function.
5. No deeply nested code
Deeply nested code, poorly readable, creates a sense of "awe". for example:
fetchData1(data1 =>
fetchData2(data2 =>
fetchData3(data3 =>
fetchData4(data4 =>
fetchData5(data5 =>
fetchData6(data6 =>
fetchData7(data7 =>
done(data1, data2, data3, dat4, data5, data6, data7)
)
)
)
)
)
)
)
Below are several common deeply nested scenarios.
1. Callback Hell
Using callback functions to handle multiple serial asynchronous operations will result in deep nesting. Commonly known as "callback hell". like:
fetchData1(data1 =>
fetchData2(data2 =>
fetchData3(data3 =>
done(data1, data2, data3)
)
)
)
2.if deeply nested
In the conditional statement, if there are many judgment conditions, there will be deep nesting or long judgment conditions. For example, to determine whether a value is: an even number between 1 and 100 that is divisible by 3 and 5. Write this:
const isEvenNum = num => Number.isInteger(num) && num % 2 === 0
const isBetween = num => num > 1 && num < 100
const isDivisible = num => num % 3 === 0 && num % 5 === 0
if (isEvenNum(num)) { // 是偶数
if(isBetween(num)) { // 1 到 100 之间
if(isDivisible(num)) { // 能被 3 和 5 整除
return true
}
return false
}
return false
}
return false
Ternary expressions can also be deeply nested:
a > 0 ? (b < 5 > ? (c ? d : e) : (f ? g : h)) : (i ? j : k)
3. Function call nesting
Executing multiple function calls, each function output is the input of the next function, can cause deep nesting. like:
// 模拟炒蛋的过程:买蛋 -> 打蛋 -> 炒蛋 -> 上桌。
toTable( // 第四步: 上桌
fry( // 第三步: 炒蛋
handle( // 第二步: 打蛋
buy(20) // 第一步: 买蛋
)
)
)
React higher-order component nesting
In an application written in React, a component will be wrapped by many higher-order components (HOC), resulting in deep nesting. like:
class Comp extends React.Component {...}
Wrapper5(
Wrapper4(
Wrapper3(
Wrapper2(
Wrapper1(Comp)
)
)
)
)
5. React Context Nested
In applications written in React, Context can be used to manage data sharing between child components. If there is a lot of shared data and the types are different, it is easy to cause the top component Context to be deeply nested. like:
<PageContext.Provider
value={...}
>
<User.Provider
value={...}
>
<Project.Provider
value={...}
>
<ChildComp />
</Project.Provider>
</User.Provider>
</PageContext.Provider>
See the optimization scheme: here .
Summarize
Code that meets the characteristics of readable code mentioned in this article will not be bad for readability. Of course, there are many tricks to improve the readability of your code. for example:
- Limit the number of arguments to a function.
- Limit the cyclomatic complexity of the function.
- Disable the
with
statement.
To learn more skills to enhance the readability of the code, line and again recommended rules ESLint of .
The next level of code quality is: reusable code , which will be covered in the next article.
Jin Weiqiang's previous wonderful articles are recommended:
Talk about code quality - Preface
Code Quality Tier 5 - just implemented features**
Code Quality Tier 4 - Robust Code
"Cloud Recommendation" is a high-quality content column of Tencent Cloud Plus community. The cloud recommendation officer specially invites industry leaders to focus on the implementation of cutting-edge technologies and theoretical practice, and continue to interpret hot technologies in the cloud era and explore new opportunities for industry development. Click to subscribe to with one click, and we will regularly push high-quality content for you.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。