naming-cheatsheet README

The project's README from github.com/kettanaito/naming-cheatsheet. As one markdown file: README.md.

Naming cheatsheet

Naming cheatsheet


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.

English language

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.

Naming convention

Pick one naming convention and follow it. It may be camelCase, PascalCase, snake_case, or anything else, as long as it remains consistent. Many programming languages have their own traditions regarding naming conventions; check the documentation for your language or study some popular repositories on GitHub!

/* Bad */
const page_count = 5
const shouldUpdate = true

/* Good */
const pageCount = 5
const shouldUpdate = true

/* Good as well */
const page_count = 5
const should_update = true

S-I-D

A name must be short, intuitive and descriptive:

/* 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

Avoid contractions

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 = () => {}

Avoid context duplication

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) => { ... }
}

Reflect the expected result

A name should reflect the expected result.

/* Bad */
const isEnabled = itemCount > 3
return <Button disabled={!isEnabled} />

/* Good */
const isDisabled = itemCount <= 3
return <Button disabled={isDisabled} />

Naming functions

A/HC/LC Pattern

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)
getUser get User
getUserMessages get User Messages
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, while shouldComponentUpdate tells you that component will update itself, and you are only controlling when it should update. In other words, high context emphasizes the meaning of a variable.


Actions

The verb part of your function name. The most important part responsible for describing what the function does.

get

Accesses data immediately (i.e. shorthand getter of internal data).

function getFruitCount() {
  return this.fruits.length
}

See also compose.

You can use get when performing asynchronous operations as well:

async function getUser(id) {
  const user = await fetch(`/api/user/${id}`)
  return user
}

set

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

reset

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

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):

function removeFilter(filterName, filters) {
  return filters.filter((name) => name !== filterName)
}

const selectedFilters = ['price', 'availability', 'size']
removeFilter('price', selectedFilters)

See also delete.

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.

remove or delete?

When the difference between remove and delete is not so obvious to you, I'd suggest looking at their opposite actions - add and create. The key difference between add and create is that add needs a destination while create requires no destination. You add an item to somewhere, but you don't "create it to somewhere". Simply pair remove with add and delete with create.

Explained in detail here.

compose

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.

handle

Handles an action. Often used when naming a callback method.

function handleLinkClick() {
  console.log('Clicked a link!')
}

link.addEventListener('click', handleLinkClick)

Context

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 explicit filterArray would be unnecessary.


Prefixes

Prefix enhances the meaning of a variable. It is rarely used in function names.

is

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!')
}

has

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

should

Reflects a positive conditional statement (usually boolean) coupled with a certain action.

function shouldUpdateUrl(url, expectedUrl) {
  return url !== expectedUrl
}

min/max

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))
}

prev/next

Indicate the previous or the next state of a variable in the current context. Used when describing state transitions.

async function getPosts() {
  const prevPosts = this.state.posts

  const latestPosts = await fetch('...')
  const nextPosts = concat(prevPosts, latestPosts)

  this.setState({ posts: nextPosts })
}

Singular and Plurals

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']

naming-cheatsheet (kettanaito/naming-cheatsheet)

Searching Database…

这是什么?这是一份与编程语言无关的速查表,介绍代码中变量和函数的命名规范,核心是 A/HC/LC(Action/High Context/Low Context,动作/高上下文/低上下文)命名模式。
这是工具,还是只是一份参考文档?它是一份参考文档(基于 README 的速查表),不是需要安装或运行的代码。示例使用 JavaScript 编写,但这些规则适用于任何语言。
它是怎么组织的?我应该从哪里开始读?它先介绍通用原则(英文命名、统一约定、S-I-D、避免缩写和上下文重复),然后进入专门讲解基于 A/HC/LC 模式的函数命名一节,之后是常用动作动词、上下文用法和前缀的列表。
用它需要什么工具吗?不需要,它只是一份供阅读的文档;无需任何安装、依赖或特定语言的工具。
这是强制规则,还是只是建议?这些是建议和约定,并非强制规则;有些指导明确依赖特定语言的约定(例如 JavaScript 中的 filter 与 filterArray)。
A/HC/LC 模式到底是什么意思?这是一个命名函数的公式:前缀(Prefix,可选)+ 动作(Action,即动词,如 get/set/handle)+ 高上下文(High Context,即主要实体,如 User)+ 低上下文(Low Context,即更具体的限定词,如 Messages),例如 getUserMessages。
上下文的顺序为什么重要?因为高上下文承载更多含义:shouldUpdateComponent 表示你即将触发一次更新,而 shouldComponentUpdate 表示组件自己更新,你只是在控制更新的时机。
remove 和 delete 该怎么选?remove 与 add 配对,delete 与 create 配对:remove 表示从某个位置拿走某物(如从列表中 removeFilter),delete 表示彻底删除某物(如 deletePost),与各自的反义词相对应。
速查表推荐布尔值和状态使用哪些前缀?布尔条件使用 is、has 和 should;边界使用 min/max;状态切换使用 prev/next。
Creator
kettanaito
Size
0.1 MB
Stars
14.2K
Updated
CommitApr 06
Age
9y
Commits · 90 Days