- Naming convention
- S-I-D
- Avoid contractions
- Avoid context duplication
- Reflect expected result
- Naming functions
- Singular and Plurals
Naming things is hard. This sheet attempts to make it easier.
Although these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.
Pick one naming convention and follow it. It may be cammelCase
, or snake_case
, or anyhow else, it does not matter. What matters is for it to remain consistent.
/* 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
A name must be short, intuitive and descriptive:
- Short. A name must not take long to type and, therefore, remember;
- Intuitive. A name must read naturally, as close to the common speech as possible;
- Descriptive. A name must reflect what it does/possesses in the most efficient way.
/* 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 hasPagination = postsCount > 10
const shouldDisplayPagination = postsCount > 10 // alternatively
Do not use contractions. They contribute to nothing but decreased readability of the code. Finding a short, descriptive name may be hard, but contraction is not an excuse for not doing so.
/* Bad */
const onItmClk = () => {}
/* Good */
const onItemClick = () => {}
A name should not duplicate the context in which it is defined. Always remove the context from a name if that doesn't decrease its readability.
class MenuItem {
/* Method name duplicates the context (which is "MenuItem") */
handleMenuItemClick = (event) => { ... }
/* Reads nicely as `MenuItem.handleClick()` */
handleClick = (event) => { ... }
}
A name should reflect the expected result.
/* Bad */
const isEnabled = itemsCount > 3
return <Button disabled={!isEnabled} />
/* Good */
const isDisabled = itemsCount <= 3
return <Button disabled={isDisabled} />
There is a useful pattern to follow when naming functions:
prefix? + action (A) + high context (HC) + low context? (LC)
Take a look at how this pattern may be applied in the table below.
Name | Prefix | Action (A) | High context (HC) | Low context (LC) |
---|---|---|---|---|
getPost |
get |
Post |
||
getPostData |
get |
Post |
Data |
|
handleClickOutside |
handle |
Click |
Outside |
|
shouldDisplayMessage |
should |
Display |
Message |
Note: The order of context affects the meaning of a variable. 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 a variable.
The verb part of your function name. The most important part responsible for describing what the function does.
Accesses data immediately (i.e. shorthand getter of internal data).
function getFruitsCount() {
return this.fruits.length
}
See also compose.
Declaratively sets a variable with value A
to value B
.
const fruits = 0
function setFruits(nextFruits) {
fruits = nextFruits
}
setFruits(5)
console.log(fruits) // 5
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
Requests for a data, which takes time (i.e. async request).
function fetchPosts(postCount) {
return fetch('https://api.dev/posts', {...})
}
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):
function removeFilter(filterName, filters) {
return filters.filter((name) => name !== filterName)
}
const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)
See also delete.
Completely erazes something from the realms of existence.
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()
}
See also remove.
Creates new data from the existing one. Mostly applicable to strings, objects, or functions.
function composePageUrl(pageName, pageId) {
return `${pageName.toLowerCase()}-${pageId}`
}
See also get.
Handles an action. Often used when naming a callback method.
function handleLinkClick() {
console.log('Clicked a link!')
}
link.addEventListener('click', handleLinkClick)
A domain that a function operates on.
A function is often an action on something. It is important to state what is its operable domain, or at least an expected data type.
/* A pure function operating with primitives */
function filter(predicate, list) {
return list.filter(predicate)
}
/* Function operating exactly on posts */
function getRecentPosts(posts) {
return filter(posts, (post) => post.date === Date.now())
}
Some language-specific assumptions may allow omitting the context. For example, in JavaScript, it's common that
filter
operates on Array. Adding explicitfilterArray
would be unnecessary.
--
Prefix enhances the meaning of a variable. It is rarely used in function names.
Describes a characteristic or state of the current context (usually boolean
).
const color = 'blue'
const isBlue = color === 'blue' // characteristic
const isPresent = true // state
if (isBlue && isPresent) {
console.log('Blue is present!')
}
Describes whether the current context possesses a certain value or state (usually boolean
).
/* Bad */
const isProductsExist = productsCount > 0
const areProductsPresent = productsCount > 0
/* Good */
const hasProducts = productsCount > 0
Reflects a positive conditional statement (usually boolean
) coupled with a certain action.
function shouldUpdateUrl(url, expectedUrl) {
return url !== expectedUrl
}
Represent minimum or maximum value. Used when describing boundaries or limits.
/**
* Renders random amount of posts within
* the given min/max boundaries.
*/
function renderPosts(posts, minPosts, maxPosts) {
return posts.slice(0, randomBetween(minPosts, maxPosts))
}
Indicate the previous or the next state of a variable in the current context. Used when describing state transitions.
function fetchPosts() {
const prevPosts = this.state.posts
const fetchedPosts = fetch('...')
const nextPosts = concat(prevPosts, fetchedPosts)
this.setState({ posts: nextPosts })
}
Like a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.
/* Bad */
const friends = 'Bob'
const friend = ['Bob', 'Tony', 'Tanya']
/* Good */
const friend = 'Bob'
const friends = ['Bob', 'Tony', 'Tanya']