译:命名规范速查表

115 阅读6分钟

编者注:==这份命名规范速查表==总结了前端开发中变量和函数命名的核心原则:1) 使用英语命名,保持一致性;2) 遵循 S-I-D 原则(简短、直观、描述性);3) 避免缩写和上下文重复;4) 函数命名采用 A/HC/LC 模式(动作+高上下文+低上下文)。特别强调了 ==get/set==、==remove/delete== 等动词的精确使用差异,以及 ==is/has/should== 等前缀的语义区分。

命名规范速查表


命名是困难的。本文档试图让它变得简单些。

虽然这些建议适用于任何编程语言,但我会用 JavaScript 来举例说明。

英语语言

使用英语命名变量和函数。

/* 错误示范 */
const primerNombre = "Gustavo";
const amigos = ["Kate", "John"];

/* 正确示范 */
const firstName = "Gustavo";
const friends = ["Kate", "John"];

无论喜欢与否,英语是编程中的主导语言:所有编程语言的语法都是用英语编写的,还有无数的文档和教育材料。用英语编写代码可以显著提高其内聚性。

命名规范

选择一种命名规范并遵循它。可以是 camelCasePascalCasesnake_case 或其他任何形式,只要保持一致。许多编程语言对命名规范有自己的传统;请查阅你的语言文档或在 GitHub 上研究一些流行的仓库!

/* 错误示范 */
const page_count = 5;
const shouldUpdate = true;

/* 正确示范 */
const pageCount = 5;
const shouldUpdate = true;

/* 同样正确 */
const page_count = 5;
const should_update = true;

S-I-D原则

名称必须简短直观描述性

  • 简短:名称不应过长,便于输入和记忆;
  • 直观:名称应尽可能接近日常用语;
  • 描述性:名称应最有效地反映其功能/内容。
/* 错误示范 */
const a = 5; // "a" 可以表示任何东西
const isPaginatable = a > 10; // "Paginatable" 听起来极不自然
const shouldPaginatize = a > 10; // 编造动词很有趣!

/* 正确示范 */
const postCount = 5;
const hasPagination = postCount > 10;
const shouldPaginate = postCount > 10; // 替代方案

避免缩写

不要使用缩写。它们只会降低代码的可读性。找到一个简短、描述性的名称可能很难,但缩写不是借口。

/* 错误示范 */
const onItmClk = () => {};

/* 正确示范 */
const onItemClick = () => {};

避免上下文重复

名称不应重复定义它的上下文。如果不会降低可读性,总是从名称中移除上下文。

class MenuItem {
  /* 方法名重复了上下文(即 "MenuItem") */
  handleMenuItemClick = (event) => { ... }

  /* 读起来很好,如 `MenuItem.handleClick()` */
  handleClick = (event) => { ... }
}

反映预期结果

名称应反映预期结果。

/* 错误示范 */
const isEnabled = itemCount > 3;
return <Button disabled={!isEnabled} />;

/* 正确示范 */
const isDisabled = itemCount <= 3;
return <Button disabled={isDisabled} />;

函数命名

A/HC/LC模式

命名函数时有一个有用的模式:

前缀? + 动作 (A) + 高上下文 (HC) + 低上下文? (LC)

查看下表了解这个模式的应用:

名称前缀动作 (A)高上下文 (HC)低上下文 (LC)
getUsergetUser
getUserMessagesgetUserMessages
handleClickOutsidehandleClickOutside
shouldDisplayMessageshouldDisplayMessage

**注意:**上下文的顺序会影响变量的含义。例如,shouldUpdateComponent 表示_你_将要更新组件,而 shouldComponentUpdate 告诉你_组件_将更新自己,你只是控制_何时_更新。换句话说,高上下文强调变量的含义


动作

函数名称的动词部分。最重要的部分,负责描述函数_做什么_。

get

立即访问数据(即内部数据的快捷获取器)。

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

另见 compose

你也可以在异步操作中使用 get

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

set

以声明式的方式设置变量,将值 A 设为值 B

let fruits = 0;

function setFruits(nextFruits) {
  fruits = nextFruits;
}

setFruits(5);
console.log(fruits); // 5

reset

将变量设置回其初始值或状态。

const initialFruits = 5;
let fruits = initialFruits;
setFruits(10);
console.log(fruits); // 10

function resetFruits() {
  fruits = initialFruits;
}

resetFruits();
console.log(fruits); // 5

remove

从某处_移除_某物。

例如,如果你在搜索页面上有一组选定的过滤器,从集合中移除其中一个就是 removeFilter不是 deleteFilter(这也是你在英语中自然表达的方式):

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

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

另见 delete

delete

完全从存在领域中擦除某物。

想象你是一个内容编辑,有一个你想摆脱的臭名昭著的帖子。一旦你点击了一个闪亮的"删除帖子"按钮,CMS 执行了一个 deletePost 动作,不是 removePost

function deletePost(id) {
  return database.find({ id }).delete();
}

另见 remove

removedelete

removedelete 的区别对你来说不太明显时,我建议看看它们的反义词 - addcreateaddcreate 的关键区别在于 add 需要一个目的地,而 create 不需要目的地。你将一个项目add到某处,但你不"create它_到某处_"。 简单地将 removeadd 配对,deletecreate 配对。

详细解释见这里

compose

从现有数据创建新数据。主要适用于字符串、对象或函数。

function composePageUrl(pageName, pageId) {
  return pageName.toLowerCase() + "-" + pageId;
}

另见 get

handle

处理一个动作。常用于命名回调方法。

function handleLinkClick() {
  console.log("点击了一个链接!");
}

link.addEventListener("click", handleLinkClick);

上下文

函数操作的领域。

函数通常是对_某物_的动作。说明其可操作领域或至少是预期的数据类型很重要。

/* 操作原始值的纯函数 */
function filter(list, predicate) {
  return list.filter(predicate);
}

/* 专门操作帖子的函数 */
function getRecentPosts(posts) {
  return filter(posts, (post) => post.date === Date.now());
}

一些特定语言的假设可能允许省略上下文。例如,在 JavaScript 中,filter 通常操作数组。添加显式的 filterArray 是不必要的。


前缀

前缀增强了变量的含义。在函数名称中很少使用。

is

描述当前上下文的特征或状态(通常是 boolean)。

const color = "blue";
const isBlue = color === "blue"; // 特征
const isPresent = true; // 状态

if (isBlue && isPresent) {
  console.log("蓝色存在!");
}

has

描述当前上下文是否具有某个值或状态(通常是 boolean)。

/* 错误示范 */
const isProductsExist = productsCount > 0;
const areProductsPresent = productsCount > 0;

/* 正确示范 */
const hasProducts = productsCount > 0;

should

反映一个肯定的条件语句(通常是 boolean)与某个动作结合。

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

min/max

表示最小或最大值。用于描述边界或限制。

/**
 * 在给定的 min/max 边界内
 * 渲染随机数量的帖子。
 */
function renderPosts(posts, minPosts, maxPosts) {
  return posts.slice(0, randomBetween(minPosts, maxPosts));
}

prev/next

表示当前上下文中变量的前一个或下一个状态。用于描述状态转换。

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

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

  this.setState({ posts: nextPosts });
}

单复数形式

像前缀一样,变量名可以根据它们是保存单个值还是多个值而变为单数或复数。

/* 错误示范 */
const friends = "Bob";
const friend = ["Bob", "Tony", "Tanya"];

/* 正确示范 */
const friend = "Bob";
const friends = ["Bob", "Tony", "Tanya"];

译者:Claude 3.5 Sonnet