如何快速给类、函数和变量命名


A/HC/LC 命名法 —— (P)A/HC/LC是什么

prefix? (P) + action (A) + high context (HC) + low context? (LC)
// 前缀 + 动作 + 高语境 + 低语境

Prefix

  • prefix(前缀)增加函数的可读性

- is (是什么)

  • 描述当前上下文(语境)的特征或状态,通常为布尔值。
    const color = 'blue'
    const isBlue = ( color === 'blue' ) // 特征
    const isPresent = true // 状态
    
    if (isBlue && isPresent) {
    console.log(‘Blue is present’)
    }

- has (有什么)

  • 描述当前上下文(语境)是否具有某个特定的值或状态,通常为布尔值
    /* Bad */
    const isProductsExist = (productsCount > 0)
    const areProductsPresent = (productsCount > 0)
    
    /* Good */
    const hasProducts = (productsCount > 0)

- should (应该做什么)

  • 映射具有明确动作的条件语句,通常为布尔值
    function shouldUpdateUrl(url, expectedUrl) {
      return (url !== expectedUrl)
    }

函数的核心是 Actions

  • Actions(动作),是函数名的动词部分,描述这个函数要做什么

- get (获取数据)

// 快速获取内部数据
function getFruitsCount() {
  return this.fruits.length;
}

- set (设置数据)

// 将某个变量的值由A变为B
let fruits = 0
function setFruits(nextFruits) {
  fruits = nextFruits
}
setFruits(5)
console.log(fruits) // 5

- reset (还原数据)

// 将某个变量的值设为其初始值或状态
let initialFruits = 5
let fruits = initialFruits
setFruits(10)
console.log(fruits) // 10
function resetFruits() {
  fruits = initialFruits
}
resetFruits()
console.log(fruits) // 5

- fetch (请求数据)

  • 通常为一个比较耗时的操作,如:异步请求
    function fetchPosts(postCount) {
      return fetch(‘https://api.dev/posts', {})
    }

- remove (移除数据)

  • 逻辑上的删除,数据可能只是被移动某个特定的地方了
  • 假设页面有个搜索过滤器,可以通过 removeFilter 来移除过滤器的某个值,而不是 deleteFilter
    function removeFilter(filterName, filters) {
      return filters.filter(name => name !== filterName)
    }
    const selectedFilters = ['price', 'availability', 'size']
    removeFilter('price', selectedFilters)

- delete (删除数据)

  • 将某个数据彻底删除, 是物理上的删除.
  • 假设你是一个文章审核员, 看到一篇不合规的文章, 当你想彻底删除这篇文章并点击 删除文章 按钮的时候, 执行的应该是一个 deletePost 的删除动作, 而不是 removePost
    function deletePost(id) {
      return database.find({ id }).delete()
    }

- compose (组合数据)

  • 基于现有的数据来创建一个新的数据, 适用于字符串、对象和函数
    function composePageUrl(pageName, pageId) {
      return ${pageName.toLowerCase()}-${pageId}
    }

- handle (处理数据)

  • 处理某个动作, 通常用来声明一个回调函数
    function handleLinkClick() {
      console.log('Clicked a link!')
    }
    link.addEventListener('click', handleLinkClick)

最后是 Context

  • context 是一个域, 指代当前函数的执行环境
  • 函数通常是处理某件事的一个动作, 所以注明函数所属的域, 或者至少注明一个预期的数据类型是很重要的
    /* 基于内置方法的纯函数 */
    function filter(predicate, list) {
    return list.filter(predicate)
    }
    /* 确切的表明这个函数是处理 posts 的 */
    function getRecentPosts(posts) {
    return filter(posts, (post) => post.date === Date.now())
    }
  • 一些编程语言允许你省略 context, 比如在 JavaScript 中 filter 方法只存在于数组上, 所以没必要给函数添加 context.

综上总结

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

提高代码可读性的变量命名技巧参考

  1. 遵循 S-I-D 原则
    /* Bad */
    const a = 5 // "a" 没有什么含义
    const isPaginatable = (postsCount > 10) // "Paginatable" 听起来很不自然
    const shouldPaginatize = (postsCount > 10) // "Paginatize" 编造一个动词更加荒谬!
    
    /* Good */
    const postsCount = 5
    const hasPagination = (postsCount > 10)
    const shouldDisplayPagination = (postsCount > 10) // alternatively
  • 避免缩写
  • 不要使用缩写形式, 这会降低代码可读性. 起一个简短并且语义化的名称可能有点难度, 但是不要让这成为你使用缩写的借口
    /* Bad */
    const onItmClk = () => {}
    /* Good */
    const onItemClick = () => {}
  • 避免重复的上下文
  • 如果命名中的 context 存在与否不会降低其可读性的话, 最好还是移除它:
    class MenuItem {
      /* 命名中的 "MenuItem" 与类名的域重复 */
      handleMenuItemClick = (event) => { ... }
    
      /* 去掉 "MenuItem", 看起来更简洁 */
      handleClick = (event) => { ... }
    }
  • 应该映射预期结果
    /* Bad */
    const isEnabled = (itemsCount > 3)
    return <Button disabled={!isEnabled} />
    /* Good */
    const isDisabled = (itemsCount <= 3)
    return <Button disabled={isDisabled} />
  • 考虑单数和复数形式
  • 因为一个变量可能拥有单个或多个值, 所以命名的时候也要考虑单数和复数形式.

参考原文链接

一些常用命名汇总(摘抄

动词 含义 返回值
can 判断是否可执行某个动作(权限) 布尔值,true:可执行;false:不可执行
has 判断是否含有某个值 布尔值,true:含有;false:不含有
is 判断是否为某个值 布尔值,true:为某个值;false:不为某个值
get 获取某个值 任何值
set 设置某个值 无返回值
load 加载某些数据 视场景定
search 搜索某些数据 视场景定
validate 校验、验证某些规则 无返回值
query 查询某些数据 视场景定
add 增加、添加数据 无返回值
create 创建数据 无返回值
update 更新某个数据 无返回值
modify 变更某个数据 无返回值
edit 编辑某个数据 无返回值
delete 删除某个数据 无返回值
initialize 初始化某个数据 无返回值
select 选择某个数据 视场景定
cancel 取消某个操作 无返回值
confirm 确认某个操作 无返回值
click 点击某个元素 视场景定
submit 提交某个数据 无返回值

  目录