• 个人代码规范分享


    前言

    本文总结了下我在前端开发过程中编写JavaScript的一些习惯的代码规范,以前端开发背景为主,但有些规则也适用其他语言。同时此规范并不绝对,仅供参考。

    命名规范

    变量长度:
    变量名不要太长,尽量不超过5个单词,若太长可以使用单词缩写

    变量缩写:
    变量缩写可以采用两种缩写方案:

    1.使用单词前几个字母,能表述含义即可,控制在3-5个字母(具体长度自定)。如:

    医院:hosp
    医生:doc
    选项:opt
    

    2.若页面内同时出现“文档”和“医生”那么doc会冲突,可以适当增加长度或变换单词来区分。如:

    文档:docs
    医生:doct
    

    3.使用单词的重音字母,使人能看到字母联想到单词。如:

    产品:pdt
    配置:cfg
    检查:chk
    

    函数命名

    操作类函数:
    一般使用动词,配合各类形容词,大致如下:
    1.纯动词。如:

    save()
    delete()
    close()
    

    2.动词+名词。如:

    保存医生:saveDoc()
    删除医院:delHosp()
    创建产品:createPdt()
    

    3.动词+形容词+名词。如

    删除选中的医生:delSelectDoc()
    追加一个临时医院:appendTempHosp()
    保存所有产品:saveAllPdt()
    

    获取数据类函数:
    统一使用get开头。如:

    getDocList()
    getDisablePdt()
    getElementById(id)
    

    从网络获取数据类函数:
    统一使用load开头。如:

    获取省份数据:loadProvince()
    根据省份ID获取市区数据:loadCityByProvinceId(pid)
    根据市区ID获取县数据:loadCountyByCityId(cid)
    

    load与get的区别个人认为在于,get更通用,可以用于代码内部的数据处理逻辑,load更倾向于从远程加载。

    事件响应函数:
    on+(动词/操作)+元素+事件名。如

    点击保存按钮:onSaveBtnClick()
    点击添加按钮:onAddBtnClick()
    当是否可用复选框变更时:onIsEnableChkChange()
    头像图片鼠标移入时:onHeaderImgMouseEnter()
    

    也可以是on+元素+(动词/操作/用途)+事件名。如

    onBtnSaveClick()
    onChkIsEnableChange()
    

    看个人习惯即可。

    虽然看上去略繁琐,但通过函数名本身,就可以完整的定位到此函数的用途。例如onIsEnableChkChange函数名:

    1. 看到on开头,知道这是一个响应界面操作事件的函数
    2. 看到isEnable,知道这是“是否可用”的功能的元素。
    3. 看到chk,知道这是一个复选框checkbox元素的事件
    4. 看到末尾的Change,知道这是一个change事件的响应函数
    5. 综上,看到命名,就可以联想到网页上有一个 名叫xxx是否可用的复选框,这是点击了这个复选框后的事件

    变量命名

    变量单词连接符:
    不使用单词连接符,使用小驼峰式命名。如

    btnSaveClick
    

    布尔值类型变量:
    统一使用is开头。如

    是否可用:isEnable
    是否选中:isCheck
    是否删除:isDelete
    

    集合类型变量:
    统一使用List结尾。如

    食品列表:foodList
    医生列表:docList
    已选产品列表:selectPdtList
    

    数组循环体内临时变量:
    若循环体代码量少,或仅一行lambda表达式,则可简写 docd, pdtp
    循环体代码量大时,或嵌套循环时,尽量使用Item结尾。如docItem, pdtItem
    不强制要求,仅为区分层级关系

    字典变量:
    统一使用Dic(Dictionary)结尾,如

    openWithDic
    exeDumpDic
    

    枚举集合:
    统一使用Enum(Enumeration)结尾。如

    医生类型枚举:docTypeEnum
    产品状态枚举:pdtStatusEnum
    服务器状态码枚举:serverCodeEnum
    

    枚举项:
    建议使用全大写,使用下划线连接单词,与常量规则一致。如

    服务器返回值失败:serverCodeEnum.ERROR
    服务器返回值成功:serverCodeEnum.SUCCESS 
    

    jQuery变量:
    建议使用$开头,或J_开头,风格统一即可。

    $saveBtn
    J_saveBtn
    

    函数变量:
    建议使用FnCb结尾,标明此变量为函数指针。如

    钩子函数:hookFn
    响应回调函数:responseCb
    回调函数:callback
    

    常量:
    统一使用全大写字母,单词用下划线连接。如

    MAX_SIZE
    TIME_OUT
    

    类(Class)构造函数:
    统一使用大驼峰式命名。如

    ListView
    DataTable
    TableView
    

    类私有属性:
    如果未使用TypeScript或其他强类型语言,即若没有使用带有访问修饰符(publicprivate等)的语言开发,应该通过变量名本身即可区分是私有属性还是公开属性。
    私有属性以及私有函数,应统一以下划线开头。如

    _data
    _pdtList
    _getData()
    _setData()
    

    目的在于给与类的使用者可以通过变量区分,哪些是可以使用的公开属性和方法,哪些不应该使用的私有属性以及不应该调用的私有方法。

    组件事件命名:
    1.统一使用on开头。如

    onClick(e)
    onSubmit(e)
    

    2.关键流程类事件,应提供after事件和before事件,以onBefore和onAfter开头。如

    准备提交前事件:onBeforeSubmit
    提交后事件:onAfterSubmit
    准备展开前事件:onBeforeExpand
    删除后事件:onAfterDel
    

    3.属性/状态变更类事件,应以on开头,changed结尾。如

    check属性变更时事件:onCheckedChange
    select属性变更时事件:onSelectedChange
    产品状态变更时事件:onPdtStatusChange
    

    代码建议

    1. 善用变量缓存
    2. 重复使用多次的字符串必须缓存
    3. 善用枚举变量,减少后期维护成本
    4. 类方法应全部挂载到原型对象
    5. 不应该使用类私有全局变量,应使用类静态变量
    6. 尽量减少闭包代码,以减少可能会出现的问题的概率
    7. 应坚持“先定义,后使用”的规范。以减少js默认的定义提升的坑
    8. 整个代码应该应只有一个入口函数,即创建一个init函数,来执行所有初始代码,而不是整篇代码随定义,随执行
    9. 事件绑定类函数应放在同一处执行,减少维护成本
    10. 善用#region 创建代码块,不同功能的代码归类,初始化类,事件绑定类,界面交互类,纯数据处理工具类等。
    11. 模块类文件,所有导出变量应全部定义在尾部。方便查阅
    12. 尽可能不创建全局变量,不注册全局事件,为后期方便转型为单页应用
    13. 尽量将代码纯数据逻辑与界面交互逻辑分开,方便后期写测试用例
    14. 尽量将所有变更定义放置在 文件/函数 内顶部
    15. 善用try catch和throw Error
    16. 不要在数组内存放不同类型的数据,一个数组应只存放一种数据类型变量,方便强类型识别与纠错
    17. 尽可能不要创建类数组变量
    18. 尽可能不使用eval、with
    19. 多写注释!推荐jsdoc风格注释,方便一键抽取注释生成代码文档
    20. 推荐使用flowjs或ts等类型描述语言来约束、规范、纠错和智能感知。

    附:关于js中的对象、字典与枚举的关系

    以上个人经验在组内分享时,有同学提出疑问:

    为什么会有字典变量,以及枚举变量,这从本质上不都是Object对象么?

    关于这个问题我是这么理解的,在js中确实对象是最强大的,任何在其他语言当中的类似对象的数据结构,在js里都可以是对象。但也正因为如此宽泛,让我们的使用过程中会产生一些疑惑或误解,才需要对各种的对象做分类。
    所以回过头来再说对象字典枚举的关系。

    他们的相同点:
    他们都是键值对集合(KeyValuePair)
    他们的Key都不能重复

    他们的不同点:
    对象:
    对象的的Key可以是字符串类型或数值类型。如果同时包含这两种就类数组对象,比如document.getElementBy...系列函数的返回值:HTMLCollection,再比如HTML元素的子元素集合:NodeList,以及HTML元素的属性值:NamedNodeMap,等都是类数组对象。
    对象的Value的类型,可以是任意类型。而且是在一个对象变量中的Value都可以是任意类型,如JSON对象。

    字典:
    而字典的Key一定是字符串类型的(其他语言中不是,受限于js语言),字典的Value也可以任意类型,但在一个字典对象变量中的所有Value一定是相同类型,也就是说字典其实是个Object<string, TValue>
    例:比如前面刚刚提到的HTML元素的attributes属性值:NamedNodeMap,就是应该一个典型的字典对象:它属于Dictionary<string, Attr>
    但是奇葩的是NamedNodeMap也支持数组下标式访问,所以它同时也是一个List<Attr>,在js里只能归结于他是类数组对象的范畴内了。

    枚举:
    而最后的枚举对象的范围会更小,枚举的值一般为基本数据类型,在其他语言中甚至只能是数值类型。
    例如,定义一个枚举对象用于一组常量:

    // 服务器接口返回值状态码枚举
    var serverCodeEnum = {
        SUCCESS : 0,
        ERROR : 1,
        XXXXX : 2,
        XXXXX : 3,
    }
    

    TypeScript中的枚举变量

    在TypeScript为了照顾js语言的日常使用,把enum关键字的编译后代码做成了双向访问的类数组对象。
    也就是既可以用过名称获得数值,也可以通过数值获得名称。使用非常方便:

    【TypeScript代码中的枚举】
    enum ownerTypeEnum {
        public = 0,
        private
    }
    
    【编译为JS后的代码】
    var ownerTypeEnum;
    (function (ownerTypeEnum) {
        ownerTypeEnum[ownerTypeEnum["public"] = 0] = "public";
        ownerTypeEnum[ownerTypeEnum["private"] = 1] = "private";
    })(ownerTypeEnum || (ownerTypeEnum = {}));
    
    // 效果:
    // ownerTypeEnum.private -> 1
    // ownerTypeEnum[1] -> "private"
    

    最后

    此类文章非常容易引战,所以再次声明以上仅个人习惯以及经验的分享,每个人都有自己的习惯,不管采用哪种习惯其实都可以。
    至少应该在组内,或是某项目内的所有成员都采用相同的一套规范,做到见名知意。

  • 相关阅读:
    hive函数之~字符串函数
    hive函数之~条件函数
    JSONP使用及注意事项小结
    css命名管理混乱?不妨试试BEM
    【移动端debug-6】如何做一个App里的web调试小工具
    ES6学习笔记(五):Class和Module
    ES6学习笔记(三):与迭代相关的新东东
    ES6学习笔记(四):异步操作
    ES6学习笔记(二):引用数据类型
    CORS跨域资源共享简述
  • 原文地址:https://www.cnblogs.com/xxcanghai/p/8027711.html
Copyright © 2020-2023  润新知