命名篇
原则 1:可读性 Readability Counts
简洁原则:英文如果存在多义词,一定要挑选一个最『平易近人』的,而不是生僻到需要查词典。
Bad
某代扣应用中用户想取消代扣,产品为了挽留用户将按钮文案定为『还是想关』而不是『取消订阅』,开发者根据其字面意思将事件回调命名为 onRescission
(“取消,废除”之意),该词佶屈聱牙。
<button ... onClick="onRescission">还是想关</button>
Good
命名为一个更常见的单词 onUnsubscribeBtnClick
而且针对对代扣场景用 unsubscribe
更能体现其订阅和取消订阅的业务属性。
<button ... onClick="onUnsubscribeBtnClick">还是想关</button>
原则 2:富有语义 Meaningful
富有语义原则:富有意义具备业务属性的命名优于含糊其辞大而宽泛的命名。宽泛命名相当于没有命名。
Bad
比如 data
(数据), process
(处理), handle
(操作)以及当做 bool 标志的 flag
,都是不好的命名。
Good
data
=>bank
(银行)process
=>addBankNamePostfix
(增加银行卡后缀)handle
=>onCardClick
(银行卡点击事件)flag
=>isDebtCard
(是否为储蓄卡)
原则 3:对仗原则 Complementary
利用对仗词汇减少理解成本,可以显著降低代码复杂度。常用对仗词:
动词
get | set | add | remove | create | destroy | start | stop | begin | end | insert | delete | show | hide | suspend | resume | lock | unlock | open | close | on | off | subscribe | unsubscribe |
---|
名词
first | last | increment | decrement | min | max | next | previous | source | destination | src | dest | soure | target |
---|
形容词或副词
old | new | active | inactive | visible | invisible | up | down |
---|
来自代码整洁之道和 C++ Programming Style Guidelines。
Not Good
处于点击态之外的另一个 tab 命名为 anotherTab 还是欠缺点意思 ?。
const anotherTabTaskId = tabs[activeTab === 0 ? 1 : 0]?.taskId;
Good
active 的对仗词是 inactive,理解成本瞬间下降 ?
const inactiveTabTaskId = tabs[activeTab === 0 ? 1 : 0]?.taskId;
Bad
{
/**
* 『查看账单』按钮曝光
*/
onBillListBtnShow() {
tracert.expo(withdrawResultSpms.viewBill.expo);
},
/**
* 点击『查看账单』
*/
onOpenUrl() {
openPage(WITHDRAW_BILL_LIST_URL);
},
}
<!-- 账单查看 -->
<div onTap="onOpenUrl" onAppear="onBillListBtnShow">
...
</div>
Good
onOpenUrl
改成 onBillListBtnClick
,和 onBillListBtnShow
对仗,让读者很容易在二者之间建立联系。
{
onBillListBtnShow() {
tracert.expo(withdrawResultSpms.viewBill.expo);
},
onBillListBtnClick() {
openPage(WITHDRAW_BILL_LIST_URL);
},
}
<div onTap="onBillListBtnClick" onAppear="onBillListBtnShow">
...
</div>
函数命名
原则 1:动宾结构
函数是用来处理数据或执行一系列流程(procedure),故必须符合 doSth 的动宾结构,如果上下文足够清晰可以省略宾语,只用动词。
Bad
账号类脱敏方法,命名 accountDesensitization
,违反动宾原则。
function accountDesensitization() {
// ...
}
Good
取名 desensitizeAccount
符合动宾结构。
function desensitizeAccount() {
// ...
}
Better
命名为 mask
,更简洁、不生僻,用暗喻更形象更易懂,因脱敏其实就是遮盖掉大部分字符,仅露出部分字符,比如手机号脱敏 18157061234
,保留前三后二变成 181******34
。
function mask() {
// ...
}
原则 2:事件回调统一前缀
事件回调以 on
或 handle
开头,项目内统一风格即可,如: onSthClick
handleSthClick
开头。
Bad
targetToCouponAll
违反该项规范。
<button onClick="targetToCouponAll">
...
</button>
Good
targetToCouponAll
=> onCouponCenterClick
。
<button onClick="onCouponCenterClick">
...
</button>
原则 3:返回布尔值的函数命名规范
通常以 is
/ has
/ can
/ should
开头,例如 React 的 shouldComponentUpdate
。
// 返回布尔值的函数
function isVisible(): boolean;
function hasLicense(): boolean;
function canEvaluate(): boolean;
function shouldSort(): boolean;
原则 4:函数命名抽象原则
函数命名应该抽象,即需要隐藏实现细节。函数名即接口(API),接口是黑盒故命名需要抽象。
Bad
该函数本意是排序某某集合,group
只是排序的手段或实现细节,应该隐藏底层实现细节,而且以后重构后不用 group
改成更好的算法,是否函数名称还得修改?第二 data
该词很宽泛,没有任何具体含义,也并未体现其集合的属性,而该函数并不是一个通用排序函数,建议使用更具业务属性的命名。
function sortAndGroupData(data) {
// ...
}
Good
sortPromotionTasks
只说明其排序的能力,并未暴露也无需暴露排序细节,符合『least knowledge principle』原则。
/**
* 将营销任务按照 xx 规则排序
* @param tasks
*/
function sortPromotionTasks(tasks) {
}
变量命名
常规变量命名
常规变量应该是一个名词,不应该携带类型,抽象而非具体,否则会导致“抽象泄露”,换言之修改变量类型,所有使用处均需改变。其他命名规则见下方。
规则一:变量应该是一个名词
Bad
/** 目标链接 */
const goPage = 'https://www.example.com/'
goPage
违反命名规范,doSth
是函数命名规则。
Good
/** 目标链接 */
const targetUrl = 'https://www.example.com/'
规则二:命名不应该携带类型
Bad
IResultObj
无需类型后缀 Obj
。
interface IResultObj {
success: boolean;
};
Good
interface IResult {
success: boolean;
};
布尔变量
布尔变量命名,善用形容词和各种时态:able
/ ible
/ ing
/ ed
。比如:visible
maintaining
finished
found
。
Bad
let imgDisable
let isTipsVisible // isXXX 一般用作函数命名。
let showTips // showTips 是动宾结构,也是函数命名,不建议当做布尔值命名
let canCollectTaskCard // 领取领取任务
Good
let imgDisabled = false;
let tipsVisible;
// 可领取的 collectible,不可领取的 uncollectible, ible 结尾表示能力“可xx”
let collectable;
枚举命名
【参考】枚举类名带上 Enum
后缀,枚举成员名称需要全大写,单词间用下划线隔开。
不做强制,遵循公司规范即可。
Good
进程状态命名:ProcessStatusEnum
,其成员名称:SUCCESS
/ UNKNOWN_REASON
。
const enum ProcessStatusEnum {
SUCCESS = 100,
UNKNOWN_REASON = 200,
}
接口命名
一、TS 接口必须 I 前缀
接口(interface)或类型(type)比如 ILbs
,目的是和 class 区分。
export interface ILbs {
city: string;
cityAdcode: string;
longitude: string;
latitude: string;
}
二、接口命名必须具备 biz specificity
即具备业务特性。
Bad
入参 IObjParamInterface 过于宽泛,但其实只被一个函数使用而已。
export function mask(objParam: IObjParamInterface): string {
}
interface IObjParamInterface {
str: string;
startNum?: number;
lastNum?: number;
formatStr: string;
}
Good
入参增加函数名 IMaskOptions
,让其更加 specific
。
export function mask(options: IMaskOptions): string {
}
interface IMaskOptions {
str: string;
startNum?: number;
lastNum?: number;
formatStr: string;
}
三、请求返回值和参数命名
[建议]: I
开头 + 业务特性 + Resp
结尾,这样一样就能知道这是返回值类型,请求参数以 Req
结尾。
Good
interface IParkingFeeResp {}
interface IParkingFeeReq {}
常量命名
对于一系列对等或相关常量,通常最后一个单词来区分其状态或用途,这样可以规范整齐地扩展到各种状态。
举例,应用状态命名:
Not Good
const APP_MAINTENANCE_STATUS = 1; // 维护中
const APP_RUNNING_STATUS = 2; // 正常运行中
Good
视觉上更加整齐,重点放在最后,肉眼更容易抓到不同之处。
const APP_STATUS_MAINTAINING = 1;
const APP_STATUS_IN_SERVICE = 2;
CSS class 命名
- class 是描述状态,应该是形容词或名词。请参考业界著名 CSS 组件库,比如 antd、bootstrap 等。
- 抽象原则,命名不要暴露底层实现,更利于以后扩展。命名是接口,接口需抽象。
- 不能含样式,比如定位(margin、left、right、center)或颜色(blue)等,否则以后样式改了类名也要修改。
- [建议] 中划线分隔
- 组件根节点命名
{组件名}-wrapper
,使用处若需要包一层,当未使用 css module,为避免冲突则命名{组件名}-usage
。
Bad
命名不规范:coupon-info-center
中 center 是样式,命名和样式耦合了,导致缺少可扩展性,假如以后改成不居中了呢?
<div class="coupon-info-center"></div>
Good
coupon-info-center
=> coupon-title-only
因为样式修改的概率远大于业务逻辑,如果样式变了,只需修改 css 即可,无需『牵一发而动全身』。
<div class="coupon-title-only"></div>
复数命名
集合命名规则。
- 可数名词加
s
,比如 cards
, items
- 不可数名词加
List
,比如 extra => extraList
- 二维数组怎么命名:可数名词 contact
sList
不可数名词 extraLists
Bad
const imagelist = JSON.parse(getIn(item, [ 'extInfos', 'imagelist' ], '[]'));
Good
image 是可数名词,改成 images
更简洁。
const images = JSON.parse(getIn(item, [ 'extInfos', 'imagelist' ], '[]'));
Bad
ActivityStatusEnumArr
后缀 Arr
定死了底层的数据结构一定是数据,不具备扩展性。
export const ActivityStatusEnumArr = [
'ON',
'OFF',
]
Good
export const activityStatusList = [
'ON',
'OFF',
]
存储字段命名
【强制】存储字段 key 是一类特殊的常量,需要让其从其他常量中区别开来,以防冲突:
- 存储 key 命名规范,以
STORAGE_KEY
开头,和普通常量显著区分开,格式:STORAGE_KEY_${BIZ_KEY}
- 示例:上一次关闭时间提示:
STORAGE_KEY_TIPS_LAST_CLOSED_TIME
- 示例:上一次关闭时间提示:
- 所有存储字段统一归纳到一个公共的常量文件管理,防止冲突,并通过 namespace 减少重复前缀
Bad
每个页面都定义自己的 key 容易被覆写或读取到其他页面的存储内容。
// page/index/index.ts
const TIPS_LAST_CLOSED_TIME = 'TIPS_LAST_CLOSED_TIME';
Good
统一到放到一个常量文件,规范管理。
// src/common/constants.ts
export const STORAGE_KEY_TIPS_LAST_CLOSED_TIME = 'TIPS_LAST_CLOSED_TIME';
export const STORAGE_KEY_UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME
= 'UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME'
Better
用 namespace STORAGE_KEYS
上下文节省 key
长度。
// src/common/constants/storage-keys.ts
export const STORAGE_KEYS = {
tipsLastClosedTime: 'TIPS_LAST_CLOSED_TIME',
uncertifiedPromotionTipsLastClosedTime: 'UNCERTIFIED_PROMOTION_TIPS_LAST_CLOSED_TIME',
}
页面、组件命名
【建议】页面以动词或名词形式呈现,组件必须是名词形式。
Good
页面以动词或名词命名均可
src/pages
├── car-moving-code-apply // 挪车码申请页。动词形式
└── discovery // 发现页。名词形式
组件以名词命名
src/components
├── auth-tips // 授权组件
├── car-moving-code-explanation-card // 挪车码使用说明卡片
└── tmall-store-list // 天猫门店列表组件
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!