给你的函数名好好取一个好名字

1,612 阅读8分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

1. 说在前面

我们生活在这个社会上,每天都要做各种trade-off, 中文译为权衡.也就是说一直在做各种选择.

在计算机世界, 亦是如此.

命名不能太长也不能太短.长了或许能够精准的阐述其作用,但是不够简洁,在《重构》这本书中也说了,如果命名太长,可以考虑自己是否已经遵守了函数或方法的单一原则。 而且手打容易出错, 屏幕宽度还得足。

长命名多了话,量多了话,编辑器的自动补足选择也长会让我眼花, 一不小心就选错了.

如果过太短了话, 描述力又差.

所以写出“好”的变量名,需要我们长时间的学习,有足够积累。

而所谓的编码水平,在绝大多多数情况下,通过变量命名就能一窥全貌.

随着经验的增加,和对于开源项目的研究,开发者对于业务的理解,语言风格的理解, 开发经验的积累,以及对于开源项目的研究.都会体现在变量命名上.

2. 变量四种命名规范

2.1 匈牙利:

别搭理这个了. 当年的 ide 的智能化还不如现在的记事本. 要确定一个变量的类型不是那么容易的. 所以有了就有匈牙利命名规范, 它要求前缀为变量类型. 比如说 int -> iUsers, float-> fMaxLength

了解一下就行

2.2 小驼峰

第一个单词首字母小写,后面其他单词首字母大.

const userList = [];
const windowTitle = "";

2.3 帕斯卡(大驼峰)

和小驼峰相对应. 每一个单词第一个都是大写

2.4 下划线命名

我们使用常量的时候也是用到了下划线.如USER_LIST.

但是下划线命名也可以深入到其他变量. 单词之间的间隔不用大小写来区分,而使用下划线来间隔.

const user_list = [];
const window_title = "";

我在开发 Flutter 之前也没使用过下划线命名的. 用过了之后才发现在文件命名的时候使用下划线是真的好, 结构清晰明了.

截屏2022-04-05 17.43.30.png

2.5 其他

由于预编译工具sassless,以及stylui是有变量的. 他们的出现改变了 CSS 命名规范的一个小小差异.

对于预编译语言中的变量, BEM,SMACSS,SUITCSS 依旧可以继续使用,变量的话,依旧可以采用上面三种中的一个相结合.

3. 函数命名方法论

3.1 常用动词

大佬指南: juejin.cn/post/701613…

3.1.1 缩写使用指导原则

  • 第一, 在不确定是否是通用的缩写的时候,就不要使用缩写. 我们的目的是保证可读性, 而不是人为的创造合作的壁垒.

    个人很反感,譬如“写出让别人看不懂的代码的时候,才是体现你价值的时候,才能保住你的工作的时候”. 劝你要善良

  • 第二, 保证整个代码的风格统一,不要有的是缩写,有的不是.

    一个所谓好的变量名,就是能够让协作的组员能够一眼看出作用,甚至能够直接代替注释

  • 第三, 缩写是作为一个单词存在的, 在命名中不是WeChat而是Wechat.

3.1.2 常用的缩写

真身缩写
definedef
functionfunc
informationinfo
statisticstat
messagemsg
internationalizationi18n
to2
for4
buttonbtn
backgroundbg
respositoryrepo
responseres
requestreq
imageimg
errorerr
navigatornav
parameterparams
utilityutil
high order componenthoc
prropertyprop
attributeattr
templatetpl
sourcesrc
horizontalhoz
veritcalvert
envirnmentenv
booleanbool

如果你看到这些缩写都很眼熟,那就正好说明这些是通用的.

  • Internationalization => i18n , i + 18 个字母 + n, 不知道当初哪位大神起头的

  • to => 2, 比如 fen2Yuan 用于讲分单位转化为元单位

3.1.3 函数命名

本来已经写了大纲了,但是想着查缺补漏网上搜索了一下.发现有一位大佬写得相当的详细,我再写的话就没有任何意义了,删了删了. 请参考 前端命名规则与各个场景的命名方法,解决你取变量名的痛苦!!!

3.2 命名长度的问题

名字长一点不可怕,可怕的是为了缩短变量名而破坏见名知意的原则。

典型的就是, react 的生命周期就是高度的语义化.

componentDidMount() {}
componentWillUnmount() {}
componentWillReciveProps() {}
getDerivedStateFromProps() {}
sholdComponentUpdate() {}
.....

上面是有些写错的地方.我故意的,没有代码编辑器就是这样的结果, 这就是语义化的缺点.在没有代码提示的情况下, 想要一次就写对实在是不现实. 但是你却很容易能够从这些很长的函数名中知道它是干啥用的.

即使个人认为命名的长度无所谓,但是在实际操作过程个人建议还是不要超过三个单词了**.当然如果你觉得四个单词实在是无法表达意思,那么长点就长点. 见名知意才是首要原则.**

如果一定要使用超过三个单词的还,可以结合下面的命名空间来综合考虑.

3.3 善用命名空间

浏览器中自带的 API 就是命名空间的最佳实践. 比如说window.Math.random(), 使用随机函数.

对于这一点,我在 先做人后做事,先学规范再写代码 一文中也有相关的阐述

举个例子:

一个购物车界面,我有删除购物车中的商品,批量删除, 添加删除数目,修改商品 sku 这四种操作逻辑,我们可以这样写:

const cart = {
  items: [],
  delItem() {},
  delItems() {},
  addItem() {},
  updateItem() {},
};

而不是cartDeleItem(){}, cardDelItems() {}, cardAddItem() {}.

在比如工具库函数中, 过滤指定数字的方法:

const tool = {
  filter: {
    number: function (value) {
      return /[1-9]\d+/.test(String(value));
    },
  },
};
// 调用
tool.filter.number("666");

3.4 统一命名

这一点非常的重要, 不管你用数字命名也好,用拼音来命名也罢,甚至瞎用缩写. 只要全局统一,都不是不可饶恕的罪过, 最多无期徒刑.

前面你用 abc 表示获取用户数据,后面又实用 cba 来表示获取用户数据. 这种一般是建议就地突突了。

相对轻一点的就是writeoutput这种语境的相近的相互混用. settingconfigconfigueconf这种交叉使用. 能够原谅,但是最好不要这么干.

3.5 要有明显的差别

相似的名字,区别要么放在开头,要么放在结尾,别放在正中间。

比如 getChineseVariable、getEnglishVariable、getJapaneseVariable 这三个名字,不同之处在正中间,很难区分。

如果编程getValChinesegetValEnglisthgetValJapanese就舒服很多

3.5 不要排斥中文命名

image.png

这个图是很久之前在知乎上看到的. 看得第一眼全部是中文命名,眉头就皱起了.但是仔细一看. 这些变量确实不好用表达出来. 它要求你较高的英语水平,还要求你的团队都有较高的英语水平. 这在国内可就太难了.

所以说在这种情况下,使用中文命名可能是更加好的选择.

3.6 先规划在编码

这是一个老方法论了. 可以应用在整个项目的各个生命周期. 甚至说是生活当中.

工作中,拿到需求的时候,不要着急马上动手去写. 边写边想写出的代码,你最多能够确保不用翻到重来,而不是代码质量.

吃透需求, 拆分成各个功能模块. 之后在动手写代码,整体不过是命名还是结构都不会太差.

3.7 让单一原则形成条件发射

我们在给函数命名的时候,经常会不知道怎么取一个更加贴切的名字.

这个时候, 你就思考, 你的函数是否符合的单一原则,一件函数只做一件事.

给只做一件事的函数来命名,显然是给做了好多件事情的函数来命名来得更加的轻松.

而且只做一件事的函数名也很难有多长.

3.8 多看源代码

多研究开源代码,给自己代码的提升不单单是对于这个语言的理解,编程的理解,它是一个全方面的提升. 自然就包括对于命名的理解.

优秀的源代码之间都是会有共同的默契的,看多了,对于各种缩写和命名习惯自然就能够做到了然于胸了.

值的注意的是,倒不必迷恋那些开源框架的源码。这些项目他们的业务的定义和我们平时开发的业务不是那么切合的。总的来说,还是要多思考。当你那这些命名给你产品看,他都能够看懂的时候,那就说明你的命名是妥帖的。

对于codelf 这种网站.你除了可以借鉴他们的命名之外,还有点击命名中查看别的上下文,理清别人上下文中命名的思路.