最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端最佳实践之『命名』篇

    正文概述 掘金(孟陬)   2021-03-14   823

    命名篇

    原则 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

    利用对仗词汇减少理解成本,可以显著降低代码复杂度。常用对仗词:

    动词

    getset
    addremovecreatedestroystartstopbeginendinsertdeleteshowhidesuspendresumelockunlockopencloseonoffsubscribeunsubscribe

    名词

    firstlast
    incrementdecrementminmaxnextprevioussourcedestinationsrcdestsouretarget

    形容词或副词

    oldnew
    activeinactivevisibleinvisibleupdown

    来自代码整洁之道和 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:事件回调统一前缀

    事件回调以 onhandle 开头,项目内统一风格即可,如: 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 命名

    1. class 是描述状态,应该是形容词或名词。请参考业界著名 CSS 组件库,比如 antd、bootstrap 等。
    2. 抽象原则,命名不要暴露底层实现,更利于以后扩展。命名是接口,接口需抽象。
      • 不能含样式,比如定位(margin、left、right、center)或颜色(blue)等,否则以后样式改了类名也要修改。
    3. [建议] 中划线分隔
    4. 组件根节点命名 {组件名}-wrapper,使用处若需要包一层,当未使用 css module,为避免冲突则命名 {组件名}-usage
    Bad

    命名不规范:coupon-info-centercenter 是样式,命名和样式耦合了,导致缺少可扩展性,假如以后改成不居中了呢?

    <div class="coupon-info-center"></div>
    
    Good

    coupon-info-center => coupon-title-only 因为样式修改的概率远大于业务逻辑,如果样式变了,只需修改 css 即可,无需『牵一发而动全身』。

    <div class="coupon-title-only"></div>
    

    复数命名

    集合命名规则。

    1. 可数名词加 s,比如 cards, items
    2. 不可数名词加 List,比如 extra => extraList
    3. 二维数组怎么命名:可数名词 contactsList 不可数名词 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 是一类特殊的常量,需要让其从其他常量中区别开来,以防冲突:

    1. 存储 key 命名规范,以 STORAGE_KEY 开头,和普通常量显著区分开,格式:STORAGE_KEY_${BIZ_KEY}
      • 示例:上一次关闭时间提示: STORAGE_KEY_TIPS_LAST_CLOSED_TIME
    2. 所有存储字段统一归纳到一个公共的常量文件管理,防止冲突,并通过 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介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元