This is a recently translated text1 (also my second translation 👏), with some minor modifications in certain parts of the article, and some additional content based on the original text. I hope it doesn't mislead anyone. Have Fun!
In the field of computer science, there are only two hard things: cache invalidation and naming things. — Phil Karlton
Naming can indeed be very difficult at times. But it is worth our effort to study it. Looking back, have you ever seen code like this?
const convertObj = (x, y, z) => {
const k = Object.keys(x);
return k.map((key) => {
return {
[y]: key,
[z]: x[key],
}
});
}
Can you immediately tell what it is doing? Of course, after reading through the code line by line, you might understand what it is trying to express. However, if the variable naming in this code were more elegant, we would find it easier to understand.
Good variable naming is very important, especially in dynamically typed languages, because you cannot rely on the predefined variable types to help you understand the exact meaning of the variable. However, if good naming conventions can be used in dynamically typed languages, the code can become more readable compared to statically typed languages.
Next, I will share some basic rules about naming conventions, based on my experiences over the years. I will provide examples by contrasting different basic types of variables. Let's start with arrays.
Arrays#
Array objects are collections of ordered data, where the basic types of the items are roughly the same. Since arrays contain multiple variable values, the variable names should be meaningful plural forms.
// very bad, very sad, very drama
const fruit = ['apple', 'banana', 'cucumber'];
// passable
const fruitArr = ['apple', 'banana', 'cucumber'];
// not bad
const fruits = ['apple', 'banana', 'cucumber'];
// good - "names" implies the array contents are strings
const fruitNames = ['apple', 'banana', 'cucumber'];
// elegant
const fruits = [{
name: 'apple',
genus: 'malus'
}, {
name: 'banana',
genus: 'musa'
}, {
name: 'cucumber',
genus: 'cucumis'
}];
Booleans#
Boolean types have only two values, true
or false
. Using prefixes like "is", "has", or "can" when naming variables will help readers understand the type of the variable.
// bad
const open = true;
const write = true;
const fruit = true;
// good
const isOpen = true;
const canWrite = true;
const hasFruit = true;
When encountering predicate functions (functions that return a boolean value), naming the variable after the named function can be a bit annoying.
const user = {
fruits: ['apple']
}
const hasFruit = (user, fruitName) => {
user.fruits.includes(fruitName)
}
// What should we name this boolean variable?
const x = hasFruit(user, 'apple');
Since we have already prefixed the function name with has
, we cannot name the boolean variable hasProjectPermission
. In this case, we can add check
or get
to the predicate (has) to modify it.
const checkHasFruit = (user, fruitName) => {
user.fruits.includes(fruitName)
}
const hasFruit = checkHasFruit(user, 'apple');
Numbers#
As for numeric types, think about what descriptive words can be used for numbers. Such as these words: maximum
, minimum
, total
.
// bad
const pugs = 3;
// good
const minPugs = 1;
const maxPugs = 5;
const totalPugs = 3;
Functions#
Functions should be named by combining verbs and nouns, and when the function performs some action on an object prototype, its name should reflect that. actionResource
is a naming format worth emulating. For example: getUser
.
// bad
userData(userId);
userDataFunc(userId);
totalOfItems(items);
// good
getUser(userId);
calculateTotal(items);
Typically, I use to
as a prefix for function names to indicate the conversion of variable values.
// I like it
toDollars('euros', 20);
toUppercase('a string')
When iterating over sub-items, I often use this idiomatic naming convention. When receiving a parameter in a function, the singular form of the array name should be used.
// bad
const newFruits = fruits.map(x => {
doSomething(x);
});
// good
const newFruits = fruits.map(fruit => {
doSomething(fruit)
})
Back to the Beginning#
Refactor the initial piece of code
const arrayToObject = (array, id, name) => {
const arrayList = Object.keys(array);
return arrayList.map((key) => {
return {
[id]: key,
[name]: array[key]
}
});
}
Reflecting on Myself#
// Previous naming => rsshub project
// 1. Get article list
const list = $('.con_list li h3')
.find('a')
.map((i, e) => $(e).attr('href'))
.get();
// 2. Send requests to the traversed article address links
const res = await got.get(itemUrl);
// Improved naming
const articleLists = $('.con_list li h3')
.find('a')
.map((i, list) => $(list).attr('href'))
.get();
const responseData = await got.get(itemUrl);