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


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} />
  • 考虑单数和复数形式
  • 因为一个变量可能拥有单个或多个值, 所以命名的时候也要考虑单数和复数形式.

参考原文链接


文章作者: Damao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Damao !
  目录