《JavaScript 模式》读书笔记(2)— 基本技巧3
这是基本技巧的最后一篇内容,这篇内容示例代码并不多。主要是概念比较多一点。
编码约定
确定并一致遵循约定比这个具体约定是什么更为重要。
一、缩进
无论是使用tab还是空格,只要是一致遵循的,是什么并不重要。JSLint的默认值是4个空格来缩进。那么需要对哪些内容进行缩进呢?只需要对大括号中所有的代码进行缩进。主要包含函数体、循环体(do、while、for、for-in)、if语句、switch语句和对象字面量引用的属性。
二、大括号
应该经常使用大括号,甚至在可选的情形下,都请使用大括号。从技术上来说,在if语句和for语句中如果仅有一行语句,可以不用大括号,但是为了一致性和更方便升级,最好还是使用大括号。
三、开放的大括号位置
开发人员在讲开放的大括号放置于什么位置有不同的选择,是和语句放在同一行还是放在接下来的一行中呢?
if(true) { alert("It's TRUE!"); } // 或者 if(true) { alert("It's TRUE!"); }
在这个特定的范例中,采用哪种方式只是个人习惯的不同。但是有些情形下随着大括号的位置不同,程序的执行结果也会有所不同。这是由分号插入机制导致的。
// 警告:未预期的返回值 function func() { return { name: "Batman" }; } // 其实上面实际上是这样的 function func() { // 因为这里隐式的加了分号 return undefined; { name:"Batman" }; } // 总之,应该一直使用大括号并直到将开放的大括号放置在前面语句的同一行: function func() { return { name:'Batman' }; }
注意:关于分号,和大括号一样,应该一直使用分号,甚至JavaScript解析器会隐式增加。这不仅是严格记录和代码编写方式,也会有助于避免之前范例中含糊不清的情况。
四、空格
使用空格也有助于改善代码的可读性和一致性。使用空格比较好的位置如下:
- 在分开for循环的各个部分的分号之后:例如,for (var i = 0; i < 10; i ++){…}
- 在for循环中初始化多个变量(i和最大值等):for (var i = 0, max = 10; i < max; i ++){…}
- 在限定数组项的逗号后面:var a =[1, 2, 3];
- 对象属性的逗号之后和将属性名和属性值分开的冒号之后:var o = {a: 1, b: 2};
- 分隔开函数中各个参数的逗号之后:myFunc(a, b, c)
- 在函数声明的大括号之前:function myFunc() {}
- 在匿名函数表达式之后:var myFunc = function () {}
空格的另外一个作用是用来分隔所有的操作符和操作,这也就意味着在各种操作符之后使用空格。
最后一点关于使用空格的情形是和大括号有关的,在如下情形使用空格是比较好的做法:
- 在函数中使用大括号开始符之前,例如if-else语句、循环语句和对象字面量等。
- 在大括号结束符和else或while之间。
命名约定
再次强调,保持一直的写法,比写法是什么更重要。
一、构造函数的首字母大写
JavaScript没有类,但是可以通过new调用构造函数:
var adam = new Person();
因为构造函数仍然仅仅是一个函数,它看起来是一个函数名,它和构造函数或者普通函数的行为差不多。所以使用首字母大写的方式来提供更高的可读性。
二、分隔单词
简单来说。多单词的情况下,构造函数使用大驼峰式命名法,比如MyPerson(),而对于函数和方法名可以使用小驼峰式命名法,比如myFun()。对于属性可以使用下划线分隔开每个单词,比如my_name。这样。
三、其他命名模式
此外,常量和全局变量的命名请使用变量名全部大写的约定。
还有一种使用约定来模仿功能性的做法是私有成员函数约定。
var person = { getName:function () { return this._getFirst() + ' ' + this._getLast(); }, _getFirst:function(){}, _getLast:function(){} };
尽管在JavaScript中可以实现真正的私有函数,有时候开发者发现仅仅是用一个下划线前缀来表示私有方法或者私有属性是更为简单的一种方法。在上面的例子中,getName()意味着这是API的一个公开方法,而_getFirst()和_getLast()意味着这是一个私有函数。尽管他们都是公开的普通方法,但是使用下划线前缀的表示方法可以提醒使用person对象的用户,告诉他们这些方法在其他地方不能确保一定能够正常工作,不能直接调用。
下面是一些可选择的下划线约定方式:
- 使用下划线结尾来表明是私有变量,比如name_。
- 使用一个下划线前缀来标示受保护属性,使用两个下划线前缀来标示私有属性。
- 在Fierfox中有一些属性,这些属性技术上并不是JavaScript语言的一部分,它们采用两个下划线前缀和两个下划线后缀来命名,如__proto__。
编写注释
为代码编写注释一定是十分重要的,比注释更为重要的,是及时不断的更新注释。
编写API文档
手写文档一定会让你觉得痛苦,ok,在JavaScript领域,可以使用JSDoc Toolkit或者YUIDoc来自动生成文档。当然,你要按照一定的格式。生成文档的步骤如下:
- 编写特殊格式的代码块
- 运行工具来解析代码和注释
- 发布工具解析的结果,大多数情况是采用HTML格式发布
需要学习一些特殊的标签:
/** * @tag value */
比如:
/** * 反转一个字符串 * * @param {String} 输入需要翻转的字符串 * @return {String} 翻转后的字符串 */ var reverse = function (input) { // ... return output; }
/** * 反转一个字符串 * * @param {String} 输入需要翻转的字符串 * @return {String} 翻转后的字符串 */ var reverse = function (input) { // ... return output; }
YUIDoc范例
这个东西就不写具体的示例了,仅作了解即可,网上可以找到很多例子。要注意的是,YUIDoc系统是一个和语言无关的系统,它仅仅解析注释的部分,而不解析JavaScript代码。缺点是不得不在注释中声明属性名、参数名和方法名。而优点在于该系统具有普适性,可以通过这样的方法为其他任何语言编写注释。
编写可读性强的代码
说真的,我觉得可读性这种标准,是十分虚幻且无法量化的一种标准,那什么样的代码才叫做具有良好的可读性的代码?有统一的规范、统一且良好的缩进、统一的命名等等?仅仅只是这样么?
我们要知道一件事,就是,写代码是一个持续迭代的过程,是无法一蹴而就的。我们需要在持续的迭代中优化代码,精简代码。
另外,在开发中一定要注意代码review,代码review不仅仅可以及时找出代码中的问题,也可以让团队的成员互相学习,体会不同思路在代码上的实际体现。
最后,在编写代码时,一定要使用JSLint。你要知道的是,在程序世界,工具比人更可靠。
好了,我们的基本技巧部分到这里就全部完成了,其中大部分是概念和一些可执行的方案,但是,说真的,我觉得这些具有一定的指导意义。十分重要。下一篇,会涉及到字面量与构造函数创建对象的对比,以及自定义构造函数,以及new操作符,还有内置包装构造函数等内容。