7.2 KiB
Naming cheatsheet
Naming things is hard. Let's make it easier.
This document contains systematized concepts and patterns often used when naming variables.
Summary
Guidelines
- Pick one naming convention and follow it. Whether it is
likeThis
, orlike_this
, or anyhow else, it does not matter. What matters is consistency in your code.
/* Bad */
const pages_count = 5;
const shouldUpdate = true;
/* Good */
const pagesCount = 5;
const shouldUpdate = true;
/* Good as well */
const pages_count = 5;
const should_update = true;
- Name, whether of a variable, method, or something else, should be short, descriptive and intuitive:
- Short. Variable should not take long to type and, therefore, to remember,
- Descriptive. Name of the variable should reflect what it does/possesses in the most efficient way,
- Intuitive. Name of the variable should read naturally, as close to the common speach as possible
/* Bad */
const a = 5; // "a" could mean anything
const isPaginatable = (postsCount > 10); // "Paginatable" sounds extremely unnatural
const shouldPaginatize = (postsCount > 10); // Made up verbs are so much fun!
/* Good */
const postsCount = 5;
const shouldDisplayPagination = (postsCount > 10);
- Do not use contractions. The latter contribute to nothing but decreased code readability. Finding a short, descriptive name may be hard, but don't think contractions help you in any way.
/* Bad */
const onItmClck = () => {};
/* Good */
const onItemClick = () => {};
- Name should not duplicate the context when the latter is known, and when removing the context does not decrease the name's readability:
class MenuItem {
/* Method name duplicates the context it is in (which is "MenuItem") */
handleMenuItemClick = (event) => { ... }
/* This way it reads as MenuItem.handleClick() */
handleClick = (event) => { ... }
}
- Name should reflect the expected result:
/* Bad */
const isEnabled = (itemsCount > 3);
return (<Button disabled={!isEnabled} />);
/* Good */
const isDisabled = (itemsCount <= 3);
return (<Button disabled={isDisabled} />);
HC/LC Pattern
There is a useful pattern you may follow when naming your methods:
prefix? + action (A) + high context (HC) + low context? (LC)
To illustrate, take a look at how this pattern may be applied in the table below.
Name | Prefix | Action | High context | Low context |
---|---|---|---|---|
getPost |
get |
Post |
||
getPostData |
get |
Post |
Data |
|
handleClickOutside |
handle |
Click |
Outside |
|
shouldDisplayMessage |
should |
Display |
Message |
Note: The order of the contexts affects the core meaning of a method. For example,
shouldUpdateComponent
means you are about to update a component, whileshouldComponentUpdate
tells you that component will update on itself, and you are but controlling whether it should do that right now. In other words, high context emphasizes the meaning of the variable.
Actions
Chosing a proper action name may grant explicit descriptiveness to your methods. This is a good place to start when naming your methods.
get
Accesses data immediately (i.e. shorthand getter of internal data).
function getFruitsCount() {
return this.fruits.length;
}
set
Declaratively sets a variable with value A
to value B
.
const fruits = 0;
function setFruits(nextFruits) {
fruits = nextFruits;
}
setFruits(5);
console.log(fruits) // 5
reset
Sets a variable back to its initial value or state.
const initialFruits = 5;
const fruits = initialFruits;
setFruits(10);
console.log(fruits); // 10
function resetFruits() {
fruits = initialFruits;
}
resetFruits();
console.log(fruits); // 5
fetch
Requests for a data, which takes time (i.e. async request).
function fetchPosts(postCount) {
return fetch('https://api.dev/posts', { ... });
}
remove
Removes something from somewhere.
For example, if you have a collection of selected filters on a search page, removing one of them from the collection is removeFilter
, not deleteFilter
(and this is how you would naturally say it in English as well):
const selectedFilters = ['price', 'availability', 'size'];
function removeFilter(filterName) {
const filterIndex = selectedFilters.indexOf(filterName);
if (filterIndex !== -1) {
selectedFilters.splice(filterIndex, 1);
}
return selectedFilters;
}
delete
Completely erazes something from the realms of existance.
Imagine you are a content editor, and there is that notorious post you wish to get rid of. Once you clicked a shiny "Delete post" button, the CMS performed a deletePost
action, not removePost
.
function deletePost(id) {
return database.find({ id }).delete();
}
compose
Creates a new data from the existing one. Mostly applicable to strings or objects.
function composePageUrl(pageName, pageId) {
return `${pageName.toLowerCase()}-${pageId}`;
}
handle
Handles a dedicated action. Often used in naming the callback methods.
function handleLinkClick(event) {
event.preventDefault();
console.log('Clicked a link!');
}
link.addEventListener('click', handleLinkClick);
Prefixes
Prefixes act as enhancers, indicating additional meaning behind variables.
is
Describes certain characteristic or state of the current context (returns Boolean
).
const color = 'blue';
const isBlue = (color === 'blue'); // characteristic
const isPresent = true; // state
if (isBlue && isPresent) {
console.log('The color is blue and it is present!');
}
has
Describes whether the current context possesses a certain value or state (returns Boolean
).
/* Bad */
const isProductsExist = (productsCount > 0);
const areProductsPresent = (productsCount > 0);
/* Good */
const hasProducts = (productsCount > 0);
should
Reflects a positive conditional statement (returns Boolean
) tightly coupled with a certain action.
const currentUrl = 'https://dev.com';
function shouldUpdateUrl(url) {
return (url !== currentUrl);
}
min
/max
Represent minimum or maximum value. Useful for describing boundaries or allowed limits.
function PostsList() {
this.minPosts = 3;
this.maxPosts = 10;
}
prev
/next
Indicate the previous and the next state of a variable in the current context. Useful for describing state transitions.
function fetchPosts() {
const prevPosts = this.state.posts;
const fetchedPosts = fetch('...');
const nextPosts = prevPosts.merge(fetchedPosts);
return this.setState({ posts: nextPosts });
}