代码应该以不言自明、易于理解、易于修改或扩展新功能的方式编写。因为代码被阅读的比写的多,这就是为什么如此强调干净的代码。
我们的源代码更具可读性:
- 越容易维护
- 新开发人员理解实现所需的时间更少
- 越容易发现哪些代码可以重用
在这篇博文中,我将分享一些我在一段时间内采用的一般干净编码原则以及一些特定于 JavaScript 的干净代码实践。
0.命名
不要把命名变成猜谜游戏。命名您的变量和函数,以揭示它们最初创建的意图。
这样,如果假设有新开发人员加入团队,它们将变得可搜索且更易于理解。
不好:
let x = 10; |
let y = new Date().getFullYear();
if (x > 30) {
//…
}
if (y - x >1990) {
//…
}
好:
let userAge = 30; |
let currentYear = new Date().getFullYear();
if (userAge > 30) {
//…
}
if (currentYear - userAge >1990) {
//…
}
1. 条件句
避免否定条件。消极只是比积极更难理解。
if (!userExist(user)) { //... } |
好:
if (userExist(user)) { //... } |
2. 函数应该做一件事
函数的平均行数不应超过 30 行(不包括空格和注释)。函数越小,就越容易理解和重构。尝试确保您的函数正在修改或查询某些内容,但不能同时修改或查询。
3. 使用默认参数
您的函数将只为未定义的参数提供默认值。其他虚假值例如 ‘’、""、false、null、0 和 NaN,不会被默认值替换。
坏:
function getUserData(name) { const userName = userName || "Patrick Collision"; // ... } |
好:
function getUserData(name = "Patrick Collision") { // ... } |
4. 单级抽象(SLA)
在编写任何函数时,如果您有多个抽象级别,则您的函数通常会做不止一件事情。将一个更大的函数划分为多个功能会导致可重用性和更容易的测试。
函数应该做一件事。他们应该做得很好。他们应该只做。— 罗伯特·C·马丁
坏:
function checkSomething(statement) { const REGEXES = [ // ... ]; |
const statements = statement.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => {
// …
});
});
const names= [];
tokens.forEach(token => {
// lex…
});
names.forEach(node => {
// parse…
});
}
好:
function checkSomething(statement) { const tokens = tokenize(statement); const syntaxTree = parse(tokens); syntaxTree.forEach(node => { // parse... }); } |
function tokenize(code) {
const REGEXES = [
// …
];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => {
tokens.push(/* … */);
});
});
return tokens;
}
function parse(tokens) {
const syntaxTree = [];
tokens.forEach(token => {
syntaxTree.push(/* … */);
});
return syntaxTree;
}
5. 不要忽略捕获的错误
对捕获的错误不采取任何措施不会使您能够修复该特定错误或对其做出反应。
将错误记录到控制台 (console.log) 并没有好多少,因为它经常会在打印到控制台的其他内容中丢失。
如果您在 try/catch 中包装任何代码,则意味着您认为那里可能会发生错误,因此您应该对何时发生错误进行计划。
不好: try { functionThatMightThrow(); } catch (error) { console.log(error); } |
好:
try { functionThatMightThrow(); } catch (error) { notifyUserOfError(error); reportErrorToService(error); } |
6. 尽量减少评论注释
只注释具有业务逻辑复杂性的代码部分。评论不是必需的。好的代码主要记录自身。
不好:
function hashing(data) { // The hash let hash = 0; |
// Length of string
const length = data.length;
// Loop through every character in data
for (let i = 0; i < length; i++) {
// Get character code.
const char = data.charCodeAt(i);
// Make the hash
hash = (hash << 5) - hash + char;
// Convert to 32-bit integer
hash &= hash;
}
}
好:
function hashing(data) { let hash = 0; const length = data.length; |
for (let i = 0; i < length; i++) {
const char = data.charCodeAt(i);
hash = (hash << 5) - hash + char;
// Convert to 32-bit integer
hash &= hash;
}
}
7. 删除注释代码
不要在代码库中留下注释掉的代码
8. 只导入你需要的
ES6 引入了解构。它可以将数组中的值或对象中的属性解包为不同的变量。您可以将其用于任何类型的对象或模块。
9. 保持函数参数不超过 3个
限制函数参数的数量非常重要,因为它可以更轻松地测试您的函数。拥有三个以上的参数会导致您使用每个单独的参数测试大量不同的情况。
1-3 个参数是理想的情况,如果可能,应避免任何超过此范围的参数。
通常,如果您有三个以上的参数,那么您的函数正在尝试做太多事情。这最终导致违反 SRP(单一职责原则)。
10. 使用数组展开复制数组。
不好:
const len = items.length; const itemsCopy = []; let i; |
for (i = 0; i < len; i += 1) {
itemsCopy[i] = items[i];
}
好:
const itemsCopy = [...items]; |
11. 写线性代码
嵌套代码很难理解。总是尽可能多地编写线性管道代码。它使我们的代码简单、干净、易于阅读和维护,从而使开发人员的生活更轻松。
例如,在回调上使用承诺可以多次提高可读性。
12. 使用 ESLint 和 Prettier
始终使用 ESLint 和 Prettier 来强制跨团队和开发人员使用通用的编码风格。
还可以尝试使用 JavaScript 的最新功能来编写代码,例如解构、展开运算符、异步等待、模板文字、可选链等。
13.使用适当的括号
使用运算符时,请将它们括在括号中。唯一的例外是标准算术运算符:+、- 和*,因为它们的优先级被广泛理解。强烈建议将 /、和 % 括在括号中,因为当它们一起使用时,它们的优先级可能不明确。
这提高了可读性并阐明了开发人员的意图。
14.从函数中提前返回
为避免 if 语句的深层嵌套,请始终尽可能早地返回函数的值。
不好:
function isPercentage(val) { if (val >= 0) { if (val < 100) { return true; } else { return false; } } else { return false; } } |
好:
function isPercentage(val) { if (val < 0) { return false; } |
if (val > 100) {
return false;
}
return true;
}
循环大周期肯定会消耗大量时间。这就是为什么你应该尽可能早地尝试跳出循环。