代码整洁之道 - Javascript
代码能运行是不够的。——罗伯特·C·马丁
我花了无数个小时编写、审查和设计网络产品,如果说有什么事情能给我带来最大的满足感,那就是编写良好的代码。
在我看来,编写简洁的代码不应该是老生常谈,而应该是任何软件产品的基本要求。在我职业生涯的初期,我很幸运(也很感激)能得到一些开发者的指导,对他们来说,“编写简洁的代码”是一种习惯。随着我在工程团队中不断晋升,我感到有必要将我的学习心得记录在博客上。
在这篇博客中,我探讨了十个能帮助你开启编写简洁易维护代码之旅的想法。由于我的职业生涯大部分时间都在使用 JavaScript 编写代码,因此本文的示例均基于 JavaScript。不过,这些概念也适用于任何编程语言。
1. 有意义的变量名
// Don't do this 💩
const a = 3.14;`
// Do this 👌
const PI = 3.14
2. 不使用魔法数字或字符串
// Don't do this 💩
const circumference = 2*3.14*radius;
const isAdminUser = user.type === "ADMIN";
// Do this 👌
const PI = 3.14;
const USER_ROLES = {
admin : "ADMIN",
clerk : "CLERK"
}
const circumference = 2*PI*radius;
const isAdminUser = user.type === USER_ROLES.admin;
为什么?
- 如果同一个魔法字符串出现在多个地方,则必须更改所有这些地方。
- 人工操作越多,出现拼写错误的可能性就越大。
- 魔法数字/字符串不具备自解释性。
3. 避免不必要的语境
// Don't do this 💩
const car = {
carMake: "BMW",
carColor: "Black",
carModel: "X5",
};
// Do this 👌
const car = {
make: "BMW",
color: "Black",
model: "X5",
};
4. 函数应该只做一件事
这应该是软件工程中最重要的一条规则。当一个函数执行多个操作时,很难为其编写简洁的测试用例。
// Don't do this 💩
function calculateAndDisplaySum(number1, number2) {
let sum = number1 + number2;
console.log(`Sum is ${sum}`);
}
calculateAndDisplaySum(5, 6);
// Do this 👌
function calculateSum(number1, number2) {
let sum = number1 + number2;
return sum;
}
function displaySum(number){
console.log(`Sum is ${number}`);
}
const sum = calculateSum(5,6);
displaySum(sum);
5. 论据少于2个
当参数数量少于两个时,编写有效的测试用例就容易得多。
// Don't do this 💩
function createButton(name, title, disabled, onClick){
//....
}
// Do this 👌
function createButton({name, title, disabled, onClick}){
//....
}
const addToCartBtn = createButton({
name: "addToCart",
title: "\"Add to Cart\","
disabled: false,
onClick: handleClick,
});
6. 函数参数中不能包含布尔值
标志位用于指示函数执行多项操作。函数应该只做一件事(参见第 4 点)。如果函数根据布尔值遵循不同的代码路径,请将其拆分。这有助于您的代码遵循单一职责原则。
// Don't do this 💩
distance(pointA, pointB, true)
// Do this 👌
distanceInKms(pointA, pointB);
distanceInMiles(pointA, pointB);
7. 函数命名——正确的方法
函数名应该清晰地表达其功能。最好在开发团队成员之间就函数名命名方式达成共识。这样,团队中的任何人都能更容易地理解函数的预期用途。
// This fetches data instantaneously.
const getUser = () => {};
// This function sets data to an object.
const setUser = (user) => {};
// This function gets data asynchronously.
const fetchUser = () => {}
// This function helps to render DOM.
const renderUser = () => {}
// This function helps to modify a object.
const updateUser = () => {}
// This function helps to handle event.
const handleUserCardClick = (evt) => {}
// These functions returns booleans to take decisions.
const shouldRenderUser = () => {}
const isAdminUser = () => {}
8. 条件语句上的多态性
function test (condition) {
if (condition === "A") {
// do something related to "A" here
} else if (condition === "B") {
// do something related to "B" here
} else if (condition === "C") {
// do something related to "C" here
}
}
test('A');
test('B');
test('C');
// Write it this way instead
const A = {
doTheThing: function(){
// code related to "A" here
}
}
const B = {
doTheThing: function(){
// code related to "B" here
}
}
const C = {
doTheThing: function(){
// code related to "C" here
}
}
function test (condition) {
condition.doTheThing();
}
test(A);
test(B);
test(C);
9. 使用 Promise,而不是回调函数
JavaScript 函数是一等公民,但用作回调函数却很混乱!它们不够简洁,会导致过多的嵌套。
// Don't do this 💩
get("https://datasource.url/endpoint"),
(requestErr, response, body) => {
if (requestErr) {
console.error(requestErr);
} else {
writeFile("newfile.html", body, writeErr => {
if (writeErr) {
console.error(writeErr);
} else {
console.log("File written");
}
});
}
}
);
// Do this 👌
get("https://datasource.url/endpoint"),
.then(body => {
return writeFile("newfile.html", body);
})
.then(() => {
console.log("File written");
})
.catch(err => {
console.error(err);
});
10. 评论
多少注释才算过多?对此众说纷纭。我坚信
“好的代码本身就能说明问题”这一理念。
我遵循的原则是只对具有业务逻辑复杂性的内容进行评论。
学习编写简洁代码是一个过程,而不是一个终点。
如需进一步阅读,请考虑阅读以下书籍。
文章来源:https://dev.to/swrjp/clean-code-javascript-2hla