编码规范
编码的时候遵循一定的规范,可以让你的代码增强可移植性,并且更加便于阅读和理解。加入团队的新人,在阅读了代码规范之后,可以更加快速的溶入团队,并理解其他人员开发的代码。
在一些讨论会议上,规范往往都是争论的焦点(比如缩进的形式)。所以如果你打算为你团队的编码规范提一些建议,那就准备好一场激烈的辩论和反对意见。要记住,建立和实施规范是非常重要的。
缩进
代码如果没有缩进,那基本上没法阅读了。比这更糟的是不规范的缩进,看着好像缩进了,但是乱七八糟摸不着头脑。所以缩进的使用必须规范。
有些开发人员喜欢使用tab键来缩进,因为在每一个编辑器里面都可以自己设置想要的tab值。有的人喜欢四个空格。如果团队遵循统一的规范,这也不是什么问题。比如本文就是四个空格,这也是JSLint推荐的。
那么什么该缩进呢?很简单,大括号。这样就是说包括函数体,循环,ifs,switch,以及对象字面量的属性。看看这个例子:
- function outer(a, b) {
- var c = 1,
- d = 2,
- inner;
- if (a > b) {
- inner = function () {
- return {
- r: c - d
- };
- };
- } else {
- inner = function () {
- return {
- r: c + d
- };
- };
- }
- return inner;
- }
大括号
应该使用大括号,尤其在那些可用可不用的地方,如果你的if语句或者for循环只有一句话,那么大括号不是必须的,但是这种时候最好用大括号。这可以让代码保持一致,并且便于升级。
假设你的for循环只有一句。你可以不用大括号,也不会有什么错误。
- // bad practice
- for (var i = 0; i < 10; i += 1)
- alert(i);
但是假如你以后要在这个循环里面添加其他东西呢?
- // bad practice
- for (var i = 0; i < 10; i += 1)
- alert(i);
- alert(i + " is " + (i % 2 ? "odd" : "even"));
这时候,虽然第二个alert有缩进,但他还是在循环之外的。所以,无论何时,都应该是用大括号。if语句一样:
- // bad
- if (true)
- alert(1);
- else
- alert(2);
- // better
- if (true) {
- alert(1);
- } else {
- alert(2);
- }
大括号位置
开发人员也经常争论大括号的位置,放在同一行还是下一行呢?
在具体的例子中,这是个见仁见智的问题。但也有例外,假如程序根据不同的位置做不同的解析呢?这是因为插入分号机制,js对此并不挑剔,他会在你没有添加分号的行之后帮你添加。这在函数返回一个对象字面量然后大括号写在下一行的时候出问题:
- // warning: unexpected return value
- function func() {
- return
- // 下面的读取不到
- {
- name : "Batman"
- }
- }
如果你想让这个函数返回一个有name属性的对象字面量,这个函数是做不到的,因为插入的分号,返回的应该是一个undefied值。
所以,最后的结论是,必须使用大括号,并且写在同一行。
- function func() {
- return {
- name : "Batman"
- };
- }
关于分号:跟大括号一样,必须写。这不只是推行严格的写程序的规范,更是在必要的时候解决一些不清楚的地方,比如前面的例子。
空格
正确的使用空格也可以增加程序的可读性和连贯性。写句子的时候你会在逗号和句号之后有一些停顿。在js中可以模仿这样的逻辑。
应该使用空格地方有:
◆循环中的分号之后
◆循环中的变量初始化for (var i = 0, max = 10; i < max; i += 1) {…}
◆数组中的逗号分隔符之后var a = [1, 2, 3];
◆对象字面量中的逗号var o = {a: 1, b: 2}
◆函数参数间myFunc(a, b, c)
◆在函数声明时候的大括号前面function myFunc() {}
◆匿名函数var myFunc = function () {};
另外一些使用空格比较好的地方就是在那些操作符的两边,比如+, -, *, =, <, >, <=, >=, ===, !==, &&, ||, +=,等等。
- // generous and consistent spacing
- // makes the code easier to read
- // allowing it to "breathe"
- var d = 0,
- a = b + 1;
- if (a && b && c) {
- d = a % c;
- a += d;
- }
- // antipattern
- // missing or inconsistent spaces
- // make the code confusing
- var d = 0,
- a = b + 1;
- if (a && b && c) {
- d = a % c;
- a += d;
- }
最后一个关于空格要注意的,大括号前面的空格。最好使用空格:
◆在函数定义,if-else,case,循环以及对象字面量的大括号前面使用空格
◆在大括号}与else、while之间使用空格
反对增加空格的一个说法是增加文件体积,但是在压缩之后并不存在这个问题。提高代码可读性经常被忽视的一个方面就是垂直的空格,你可以使用空行来分开代码,就好像写文章时候的段落一样。
命名规范
可以提高代码移植性和可维护性的一个方面是命名规范。也就是说,在取变量名的时候总是采取一贯的做法。
无论采用什么样的命名规范,其实都不是很重要,重要的是确定下来这个规范,然后遵守它。
构造函数首字母大写
javascript中没有类,但是可以使用new来达到同样的目的。
因为构造函数也是函数,如果能从名字上就能区别它是构造函数还是普通函数,对于开发者是非常有用的。所以将构造函数的首字母大写,普通函数的首字母小写作为提示。这样一眼就能区别。
单词的分隔
当你的变量名或者函数名是由好几个单词构成的时候,如果能顺利区分变量名由那几个单词构成,也是非常不错的体验。这种命名规范成为驼峰式。所谓驼峰式就是以小写字母开始,后面的每个单词第一个字母大写。
对于构造函数第一个字母大写,MyConstructor(),对于普通的函数,就采用驼峰式myFunction(), calculateArea()。
那么变量怎么办呢,有的人使用驼峰式,但是更好的办法是使用下划线来区分。first_name,favorite_bands, 以及 old_company_name。这也可以让你一眼就能区分函数和变量。
其他命名规范
有时候,开发人员也会使用命名规范来替代和弥补一些语言的特性。
例如,在javascript中,并没有提供定义常量的办法(虽然有Number.MAX_VALUE),所以开发人员使用全大写的名称来表示不可更改的常量。var PI = 3.14, MAX_WIDTH = 800。
另外一种规范是使用全局变量名的首字母。这样做可以强化开发者使全局变量最少,并且容易辨认。
另外一种规范是在函数中模拟私有成员。虽然可以在javascript中实现私有变量,但是开发人员为了更加容易区别,所以给他加一个下划线的前缀。例如:
- var person = {
- getName: function () {
- return this._getFirst() + ' ' + this._getLast();
- },
- _getFirst: function () {
- // ...
- },
- _getLast: function () {
- // ...
- }
- };
在这个例子中,getName是一个公有函数,是API的一部分,_getFirst,_getLast本意是私有的。虽然仍然是公有函数,但hi加上了这个前缀,表示在以后的版本中不保证能运行,所以不应该被直接使用。注意在JSLint中不推荐这样做,除非你设置nomen选项为false。
还有其他几种表示私有成员的规范:
◆在末尾使用下划线,比如name_以及getElements_
◆使用一个下划线表示保护成员_protected,两个下划线表示私有成员__private
◆在firefox中,有些不是语言原生的变量,以两个下划线开始,两个下划线结束__proto__以及__parent__
写注释
必须给你的代码写注释,就算它看起来不会被别人接手。有时候,你研究完一个问题,然后你看着代码觉得那是显而易见的,但是过一两周之后回头再看,你也会摸不着头脑的。
当然,也不能过分的注释:每个变量每一行代码都注释。但是通常都需要对函数的功能,参数,返回值写文档,以及一些其他的复杂的逻辑和算法。想想,你的代码的阅读者,只需要读注释就能大体上了解你的代码在做什么需要什么,这比直接读代码理解要快的多。当你有五六行的代码是做一个具体的任务,那么阅读者就可以通过一行代码了解你的目的,然后跳过这些代码。关于注释,没有硬性的比例说是多少代码需要多少注释。有时候,有些代码(比如正则表达式)注释的内容肯定比代码本身多。
写注释是必须遵守的规范,而且要保持注释的更新,一个过时的注释带给人的迷惑还不如不写注释。
原文链接:http://www.cnblogs.com/beiyu/archive/2011/03/03/essential-javascript.html