- JavaScript Clean Code-best Practices
- Original author: Milos Protic
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: xilihuasi
- Proofreader: Smilemuffie, Xuyuey
JavaScript plain Code — Best practice
The introduction
If you don’t just worry about whether your code will work, but also about the code itself and how it will be written, you can say that you care about simple code and practice it. Professional developers write code for their future and for other people, not just for machines. Any code you write will not be written once, but will sit there waiting to be made miserable by someone who will maintain it in the future. I hope that future guy isn’t you.
Based on the above, concise code can be defined as code written in a way that is self-explanatory, easy to understand, and easy to change or extend.
Think back to how many times your first impression of someone else’s job was one of the following WTF questions?
“What the hell is this?”
What the fuck are you doing here?
“What the hell is this for?”
There is a popular image that depicts this scene.
A quote from Robert C. Martin (Uncle Bob) should inspire you to think about your ways.
Even bad code will run. But if the code isn’t concise enough, it can get your development organization into trouble.
In this article, the focus will be on JavaScript, but the principles can be applied to other programming languages.
Here’s what you need — plain Code best practices
1. Strong type checking
Use === instead of ==
// If not handled properly, it can greatly affect the program logic. It's like, you expect to go left, but for some reason, you go right.
0= =false // true
0= = =false // false
2= ="2" // true
2= = ="2" // false
/ / case
const value = "500";
if (value === 500) {
console.log(value);
// Will not be executed
}
if (value === "500") {
console.log(value);
/ /
}
Copy the code
2. The variable
Variable names should directly indicate the intent behind them. This is easy for code to search and easy for others to understand.
Bad examples:
let daysSLV = 10;
let y = new Date().getFullYear();
let ok;
if (user.age > 30) {
ok = true;
}
Copy the code
Good example:
const MAX_AGE = 30;
let daysSinceLastVisit = 10;
let currentYear = new Date().getFullYear(); . const isUserOlderThanAllowed = user.age > MAX_AGE;Copy the code
Do not add unnecessary words to variable names.
Bad examples:
let nameValue;
let theProduct;
Copy the code
Good example:
let name;
let product;
Copy the code
Don’t force others to remember the context of variables.
Bad examples:
const users = ["John"."Marco"."Peter"];
users.forEach(u= > {
doSomething();
doSomethingElse();
// ...
// ...
// ...
// ...
// Here is the WTF scene: what is' u 'TM?
register(u);
});
Copy the code
Good example:
const users = ["John"."Marco"."Peter"];
users.forEach(user= > {
doSomething();
doSomethingElse();
// ...
// ...
// ...
// ...
register(user);
});
Copy the code
Don’t add unnecessary context.
Bad examples:
const user = {
userName: "John".userSurname: "Doe".userAge: "28"}; . user.userName;Copy the code
Good example:
const user = {
name: "John".surname: "Doe".age: "28"}; . user.name;Copy the code
3. The function
Use long, descriptive names. Given that it represents some kind of behavior, the function name should be a verb or phrase that reveals the intent behind it, as should parameters. Their names should indicate what they do.
Bad examples:
function notif(user) {
// implementation
}
Copy the code
Good example:
function notifyUser(emailAddress) {
// implementation
}
Copy the code
Avoid using too many parameters. Ideally, there should be no more than two function arguments. The fewer arguments, the easier the function is to test.
Bad examples:
function getUsers(fields, fromDate, toDate) {
// implementation
}
Copy the code
Good example:
function getUsers({ fields, fromDate, toDate }) {
// implementation
}
getUsers({
fields: ['name'.'surname'.'email'].fromDate: '2019-01-01'.toDate: '2019-01-18'
});
Copy the code
Use default parameters instead of conditional statements.
Bad examples:
function createShape(type) {
const shapeType = type || "cube";
// ...
}
Copy the code
Good example:
function createShape(type = "cube") {
// ...
}
Copy the code
A function should only do one thing. Multiple operations in a single function are prohibited.
Bad examples:
function notifyUsers(users) {
users.forEach(user= > {
const userRecord = database.lookup(user);
if(userRecord.isVerified()) { notify(user); }}); }Copy the code
Good example:
function notifyVerifiedUsers(users) {
users.filter(isUserVerified).forEach(notify);
}
function isUserVerified(user) {
const userRecord = database.lookup(user);
return userRecord.isVerified();
}
Copy the code
Set the default Object using object. assign.
Bad examples:
const shapeConfig = {
type: "cube".width: 200.height: null
};
function createShape(config) {
config.type = config.type || "cube";
config.width = config.width || 250;
config.height = config.width || 250;
}
createShape(shapeConfig);
Copy the code
Good example:
const shapeConfig = {
type: "cube".width: 200
// Exclude the 'height' key
};
function createShape(config) {
config = Object.assign(
{
type: "cube".width: 250.height: 250}, config ); . } createShape(shapeConfig);Copy the code
Do not use flag variables as arguments, as this indicates that the function does something it should not do.
Bad examples:
function createFile(name, isPublic) {
if (isPublic) {
fs.create(`./public/${name}`);
} else{ fs.create(name); }}Copy the code
Good example:
function createFile(name) {
fs.create(name);
}
function createPublicFile(name) {
createFile(`./public/${name}`);
}
Copy the code
Do not pollute global variables. If you want to extend an existing object, use ES class inheritance instead of creating functions on the prototype chain of the native object.
Bad examples:
Array.prototype.myFunc = function myFunc() {
// implementation
};
Copy the code
Good example:
class SuperArray extends Array {
myFunc() {
// implementation}}Copy the code
4. Conditional statements
Avoid negative conditions.
Bad examples:
function isUserNotBlocked(user) {
// implementation
}
if(! isUserNotBlocked(user)) {// implementation
}
Copy the code
Good example:
function isUserBlocked(user) {
// implementation
}
if (isUserBlocked(user)) {
// implementation
}
Copy the code
Use conditional statement abbreviations. This may not be that important, but it’s worth mentioning. Use this method only for booleans and make sure the values are not undefined and NULL.
Bad examples:
if (isValid === true) {
// do something...
}
if (isValid === false) {
// do something...
}
Copy the code
Good example:
if (isValid) {
// do something...
}
if(! isValid) {// do something...
}
Copy the code
Avoid conditional statements whenever possible and use polymorphism and inheritance.
Bad examples:
class Car {
// ...
getMaximumSpeed() {
switch (this.type) {
case "Ford":
return this.someFactor() + this.anotherFactor();
case "Mazda":
return this.someFactor();
case "McLaren":
return this.someFactor() - this.anotherFactor(); }}}Copy the code
Good example:
class Car {
// ...
}
class Ford extends Car {
// ...
getMaximumSpeed() {
return this.someFactor() + this.anotherFactor(); }}class Mazda extends Car {
// ...
getMaximumSpeed() {
return this.someFactor(); }}class McLaren extends Car {
// ...
getMaximumSpeed() {
return this.someFactor() - this.anotherFactor(); }}Copy the code
5. ES class
Classes are the new syntactic sugar in JavaScript. Everything is just as it was when you used the prototype now it just looks different, and you should like them better than normal ES5 functions.
Bad examples:
const Person = function(name) {
if(! (this instanceof Person)) {
throw new Error("Instantiate Person with `new` keyword");
}
this.name = name;
};
Person.prototype.sayHello = function sayHello() { / * * / };
const Student = function(name, school) {
if(! (this instanceof Student)) {
throw new Error("Instantiate Student with `new` keyword");
}
Person.call(this, name);
this.school = school;
};
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.printSchoolName = function printSchoolName() { / * * / };
Copy the code
Good example:
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
/ *... * /}}class Student extends Person {
constructor(name, school) {
super(name);
this.school = school;
}
printSchoolName() {
/ *... * /}}Copy the code
Use method chains. Many libraries, such as jQuery and Lodash, use this pattern. That way, your code will have less redundancy. In your class, just return this at the end of each function, and then you can chain calls to more class methods on it.
Bad examples:
class Person {
constructor(name) {
this.name = name;
}
setSurname(surname) {
this.surname = surname;
}
setAge(age) {
this.age = age;
}
save() {
console.log(this.name, this.surname, this.age); }}const person = new Person("John");
person.setSurname("Doe");
person.setAge(29);
person.save();
Copy the code
Good example:
class Person {
constructor(name) {
this.name = name;
}
setSurname(surname) {
this.surname = surname;
// Return this for chaining
return this;
}
setAge(age) {
this.age = age;
// Return this for chaining
return this;
}
save() {
console.log(this.name, this.surname, this.age);
// Return this for chaining
return this; }}const person = new Person("John")
.setSurname("Doe")
.setAge(29)
.save();
Copy the code
6. General principles
In general, you should try not to duplicate your work, which means you shouldn’t write duplicate code, and don’t leave a tail behind you like unused functions and dead code.
You can end up with duplicate code for a variety of reasons. For example, if you have two things that are roughly the same but slightly different, their different properties or time constraints cause you to create two separate functions that contain nearly the same code. Removing duplicate code in this case means abstracting the differences and dealing with them at that level.
About dead code, code is what it’s called. It’s code that doesn’t do anything in our code base, and at some point in development, you decide it’s no longer useful. You should search the code base for these sections and remove any unwanted functions and code blocks. The advice I can give you is to delete it once you decide you no longer need it. Or you’ll forget what it’s for.
Here’s a picture of how you might feel.
conclusion
This is just a small part of what you can do to improve your code. It seems to me that the principle in question is one that people often don’t follow. They’ve tried, but it doesn’t always work for a variety of reasons. While the project may start with clean code, these principles are often ignored and relegated to the “to do” or “refactor” section as deadlines approach. In those days, clients would rather have you meet deadlines than write clean code.
In this way!
Thanks for reading, see you in the next article.
If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.