变量命名

我想有点儿代码洁癖的人,在编写代码的过程中,或多或少地想过“如何给一个变量起一个好名?”的问题。然而,一般的编程书或代码规范都不会详细地讲这个问题,也就是一两句话带过。比如全局变量或常量全大写字母,变量名采用小驼峰。这里不仅指变量命名,还有函数或方法名、常量名、类名、对象名、文件名等。我以前也多次思考过如何缩写变量名,发现不少人采用取辅音字母方法不错,然而没有深入学习过如何给变量命名,经常起变量名时比较纠结。直到读了《代码大全》的“变量名的力量”一章发现这正是我一直想读而未读的内容,也将我以前学习的有关变量命名的内容串联起来了。

为什么要起一个好的名字?

如果代码只是一个人写,如果代码写完之后再也不看了,那起一个好的名字并不是必需的事情。然后很多情况下,不仅别人会看我们的代码,写完之后我们还会阅读自己的代码。这个时候就需要有变量命名方面的统一风格,对于那些几十上百人合作的大型多语言项目,命名方面需要规定的更细致。

命名注意事项

《代码大全》给出了多条命名时考虑的问题及指导建议,其中不少我都考虑过,然后都是零碎地思考过。

最重要的注意事项

变量名应该准确地反映出它所代表的事物,由于自己英语比较渣,母语不是英语,所以查字典也不一定能选择准确的名字,还是要靠积累。

命名风格

这个好多书或规范都会提到,常见的风格:

  • 小驼峰:首字母小写,后面所有单词首字母大写,如userName
  • 大驼峰:与小驼峰唯一区别时首字母也大写,如UserName
  • 下划线分隔:包括变量或函数常用的全小写字母、下划线分隔,如create_box,也包括全局常量的全大写字母、下划线分隔,如NAME_MAX_LEN
  • 匈牙利命名法:曾经在 Windows API 中为主流形式,目前少见;

另外还有些针对特定类型名字的风格,比如 JavaScript 私有成员命名以下划线开头,数组名字用复数形式。

名字长度

《代码大全》上面说 8 ~ 20 个字符最好,意思是最好不要超过 20 个字符,代码中也不要有很多长的名字。另外作用域对变量名也有影响,如果是不常用的全局变量可能长些,如果是临时用的局部变量就会短一些。可能最短的就是循环语句当中的索引变量,而且常用ijk

对仗词

即那些互为反义词的单词,还是会经常用到的,大部分都是简单的英文单词。

  • begin/end, start/end
  • first/last
  • min/max
  • previous/next
  • old/new
  • visible/invisible
  • source/target
  • open/close
  • show/hide
  • on/off
  • up/down
  • ...

一些特定类型变量的命名

  • 循环索引:尽量用ijk,这已经是约定俗成,绝大多数程序员都熟悉的了;
  • 状态变量:我觉得应该使用形容词,比如closedhidden等;
  • 临时变量:书中作者说尽量不要使用temp/tmp这种含义太泛的名字,应该使用所指代的含义,我觉得两个变量交换时经常使用temp/tmp可能是个例外;
  • 布尔变量:变量隐含”真/假”含义,并且不要使用isFoundisError这种形式,我自己倒是经常使用is作为前缀;
  • 枚举类型:JavaScript 中没有真正的枚举类型,但是枚举也就是一组相关的变量,可以用数组或对象表示的,使用复数形式。
  • 常量:全大写字母,下划线分隔形式。但是全大写字母对于非母语的国内程序员来说可读性其实并不好,我在 JavaScript 中见得也不多,倒是觉得g_作为前缀这种形式更好一些。另外 C 语言中全大写字母似乎是主流形式,可能还得采用。

书中还给出了 C、C++、Java 命名规则示例,区分的比较细致,比如局部变量、成员变量、函数等都要区分,自己写代码时区分的没这么细致。可能和 JavaScript 语言本身有关,或者自己没有编写过大中型项目有关。

另外书中提到了一种很好的思路:

可以通过命名方面的约定来增强某种语言的功能,从而弥补该语言自身的缺陷。

JavaScript 当中使用下划线_开头的命名表示私有成员正是这种思路的体现啊。

标准前缀

用户自定义一些单词的缩写形式作为命名的前缀,这样通过较短的名字传达更多的信息,但是会增加记忆这些前缀的成本。

如何缩写

书中列举了一些指导原则,个人常见的:

  • 标准缩写,即词典中的缩写
  • 去掉所有非前置元音字母
  • 取前几位字母
  • 取所有单词首字母
  • 参考一些开源项目当中常见的缩写形式

我觉得应该有一份 JavaScript Web 开发方面常用变量缩写形式参考表,我一般会参考一些书中或著名的开源项目中的缩写形式。比如元素element的缩写有elemel,事件对象event的缩写形式为evte,但是遇到eleev的形式后就感觉内心很不舒服,可能就像密集恐惧症患者见到含有密集物的图片一样,恨不得撕碎它。当然,也有可能是我孤陋寡闻了。

避免的名字

  • 避免使用含义完全无关的名字
  • 避免使用过于简短的名字:最讨厌使用一个字母变量的形式了;
  • 避免使用在名字中使用数字:这个我常见到一些人用2表示to,用4表示for,个人不太喜欢这种形式;
  • 避免单词拼写错误:这也是我最讨厌的错误了,花个十几秒查下词典就行了,对于那些开放 API 当中的拼写错误最应该避免了;
  • 不要使用标准类型、变量和子程序的名字:每种语言都有一些内置的类型、方法,尽量不要冲突;
  • 易混淆的名字:典型的就是I1l三个字符在某些字体下很难区分。

另外,个人认为尽量不用汉语拼音作为变量,所以这也就要英语词汇量丰富些,也要针对某方面,比如图形编程方面可能对几何、坐标、向量等方面的英文词汇要熟悉些。

总结

代码风格与变量命名风格并不是永久不变的,那些著名开源项目似乎能影响代码风格和变量命名的主流形式。项目的代码风格或变量命名尽量和主流形式一致,但也并非强制要求。

当然,对于某些连基本的代码风格都不太注意的人,更别提变量命名的风格了,这些很多书都不会讲,似乎全凭自觉了或者项目负责人的规定了。