This is a fork of https://github.com/kettanaito/naming-cheatsheet
- English language
- Naming convention
- Short, Intuitive and Descriptive
- Avoid contractions
- Avoid context duplication
- Be consistent
- 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 (except those that directly go against these conventions, like Python), I will use JavaScript and React to illustrate them in practice.
Use English language when naming your variables and functions.
/* Bad */
const primerNombre = 'Gustavo'
const amigos = ['Kate', 'John']
/* Good */
const firstName = 'Gustavo'
const friends = ['Kate', 'John']
Like it or not, English is the dominant language in programming: the syntax of all programming languages is written in English, as well as countless documentations and educational materials. By writing your code in English you dramatically increase its cohesiveness.
Pick the camelCase
naming convention, follow it and remain consistent. If you need to start classes with uppercase, pick PascalCase
for those.
/* Bad */
const page_count = 5
const shouldUpdate = true
const HasPagination = true
/* Good */
const pageCount = 5
const shouldUpdate = true
const hasPagination = 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 = a > 10 // "Paginatable" sounds extremely unnatural
const shouldPaginatize = a > 10 // Made up verbs are so much fun!
/* Good */
const postCount = 5
const hasPagination = postCount > 10
const shouldPaginate = postCount > 10 // alternatively
Do not use contractions, except for the established ones: min
, max
and prev
. 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) => { ... }
}
Names should be consistent and reflect the expected result.
/* Bad */
const isEnabled = itemCount > 3
return <Button disabled={!isEnabled} />
/* Good */
const isEnabled = itemCount > 3
return <Button enabled={isEnabled} />
/* Also good */
const isDisabled = itemCount <= 3
return <Button disabled={isDisabled} />
There is a useful pattern to follow when naming functions:
action (A) + high context (HC) + low context? (LC) + action (A)
Take a look at how this pattern may be applied in the table below.
Name | Action (A) | High context (HC) | Low context (LC) | Action (A) |
---|---|---|---|---|
getUser |
get |
User |
||
getUserMessages |
get |
User |
Messages |
|
handleClickOutside |
handle |
Click |
Outside |
|
updateUser |
update |
User |
||
userUpdate |
user |
Update |
Note: The action order affects what a variable means. For example,
updateUser
tells you this function lives outside of User and is responsible for updating a User (maybe even change it completely), whileuserUpdate
tells you this function lives inside of User and is responsible for updating this particular User.
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 getFruitCount() {
return this.fruits.length
}
See also compose.
Sets a variable in a declarative way, with value A
to value B
.
let 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
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10
function resetFruits() {
fruits = initialFruits
}
resetFruits()
console.log(fruits) // 5
Request for some data, which takes some indeterminate 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) // ['availability', 'size']
See also delete.
Completely erases 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 its operable domain is, or at least an expected data type.
/* A pure function operating with primitives */
function filter(list, predicate) {
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
}
Represents a minimum or maximum value. Used when describing boundaries or limits.
/**
* Renders a 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']