关于javascript,你必须知道,你不是一个人在战斗!
Any violation to this guide is allowed if it enhances readability.
所有的代码都要变成可供他人容易阅读的。
软件的长期价值直接源于其编码质量。在它的整个生命周期里,一个程序可能会被许多人阅读或修改。
如果一个程序可以清晰的展现出它的结构和特征,那就能减少在以后对其进行修改时出错的可能性。编程规范可以帮助程序员们增加程序的健壮性。
所有的JS代码都是暴露给公众的。所以我们更应该保证其质量和可阅读性,保持整洁很重要。
Javascript代码格式规范
1.html中外部脚本引入尽量放在尾部。
2.编码统一采用utf-8。
3.不要在html标签中混合script事件代码。
4.一个html文件中尽量只出现一个<script>代码块,所有代码块用
(function(){//代码})();
包裹,可减少全局污染。5.JS代码如果只针对特定HTML可以写在页面里,使用率高的代码块可以考虑写入公共JS文件调用。
6.程序块采用缩进风格编写,缩进采用4个空格,避免使用tab缩进以免各编辑器显示不一致。
7.一元操作符(如 delete, typeof, void)或在某些关键词(如 return, throw, case, new) 之后, 不要使用括号。
8.优先使用 '' 包裹字符串。
9.多行字符串使用 + 拼接形式, 不要使用 \ 拼接,如果需要换行,+ 请加在行尾。
10.避免多出额外的,(逗号),如:
var arr = [1,2,3,];list = {a:3,b:5,};
最后的,(逗号)多余,应删除,分别改为:
var arr = [1,2,3];list = {a:3,b:5};
这些错误一定要仔细,避免ie中报“缺少字符串,标识符或数字”的BUG。
11.作 for-in循环时应避免来自原型链上的污染。可用hasOwnProperty方法检查是否为自身成员。
12.不要吝啬你的注释。当代码块更新时,注释也要对应更新。
13.合理使用空格。空格应在以下情况下使用:
跟在“(”(左括号)后面的关键字应被一个空格隔开。如
while (true) {
函数参数与“(”(左括号)之间不应该有空格。这能帮助区分关键字和函数调用。
所有的二元操作符,除了“.”(点) 和“(”(左括号)和 “[”(左方括号)外应用空格将其与操作数隔开。
三元操作符(? :)两边要留有空格。
一元操作符与其操作数之间不应有空格,除非操作符是个单词,比如 typeof。
每个在控制部分,比如 for 语句中的 “;”(分号)后须跟一个空格。
每个 “,”(逗号)后应跟一个空格。
行尾不要有空格。
Javascript命名规则
原则:尽量避免潜在冲突;精简短小, 见名知意。
1.变量名应由26个大小写字母(A..Z,a..z),10个数字(0..9),和_(下划线)组成。避免使用国际化字符(如中文)。注意:JS是区分大小写的。
2.变量名以字母、下划线 _ 或美元符号 $ 开头,允许名称中包含字母、数字、下划线 _ 和美元符号 $ 。
3.变量名尽量采用有意义的英文单词或缩写命名,不要用拼音。
4.采用首字母小写,其它单词首字母大写的驼峰式命名,如userName,arrayIndex。
5.Object对象名要以大写开头,如:var Tabs = {}。Hash不必遵从此规则。
6.变量、参数、成员变量、函数等名称均以小写字母开头,构造器的名称以大写字母开头。
7.全局变量应该全部大写。(Javascript没有宏或者常量,所以不会因此造成误会)
8.下划线'_'开头的变量一般习惯于标识私有/局部成员。而美元符号'$'开头的变量习惯于标识系统相关,比如系统进程等。应避免用下划线'_'或美元符号'$'来命名标识符。注意:store()的属性名最好以 _ 开头避免和框架冲突。如:
el.store('_detail','el-list');
9.函数命名必须能够体现函数的功能。
10.必须与new共同使用的构造函数名应以大写字母开头。当new被省略时Javascript不会有任何编译错误或运行错误抛出。忘记加new时会让不好的事情发生(比如被当成一般的函数),所以大写构造函数名是我们来尽量避免这种情况发生的唯一办法。
11.系统级class对象,最好前面加Ex_开头避免和框架类冲突,如:Ex_Tabs
(function(){var formTime, toTime,Ex_Timer = this.Ex_Timer = new Class({$event:[],onStart:function(){},_show:function(){}}); });
12.各种页面对象在命名时考虑使用以下对应前缀:
-text 输入框: txt -button 按钮:btn -select 下拉选择框:sel -option 项: opt -form 表单:frm -hidden 表单项:hdn -窗口对象:win
特殊命名规范
1.术语 “get/set” 不要和一个字段相连,除非它被定义为私有变量。
2.前面加 “is” 的变量名应该为布尔值,同理可以为 “has”, “can” 或者 “should”。
3.术语 “compute” 作为变量名应为已经计算完成的变量。
4.术语 “find” 作为变量名应为已经查找完成的变量。
5.术语 “initialize” 或者 “init” 作为变量名应为已经实例化(初始化)完成的类或者其他类型的变量。
6.UI(用户界面)控制变量应在名称后加控制类型,例如:
leftComboBox, TopScrollPanel
7.复数必须有其公共的名称约定。
8.带有 “num” 或者 “count” 开头的变量名约定为数字(对象)。
9.重复变量建议使用 “i”, “j”, “k” (依次类推)等名称的变量。
10.补充用语必须使用补充词,例如:get/set, add/remove, create/destroy, start/stop, insert/delete, begin/end, etc.
11.避免产生歧义的布尔变量名称,例如:isNotError, isNotFound 为非法
12.错误类建议在变量名称后加上 “Exception” 或者 “Error”。
13.方法如果返回一个类,则应该在名称上说明返回什么;如果是一个过程,则应该说明做了什么。
变量
1.所有的变量必须在使用前进行声明。将 var 语句放在函数的首部。最好把每个变量的声明语句单独放到一行,并加上注释说明。
2.变量不能产生歧义。
3.少用全局变量。不要让局部变量覆盖全局变量。
4.浮点变量必须指明实部,即使它们为零(使用 0. 开头。
函数和语句
1.尽可能不要让每行超过 120 个字符,换行时应注意与上一行保持缩进。
2.语句末尾请使用 ; 结束,即使后面没有其它语句。注意一个函数赋值或对象赋值语句也是赋值语句,应该以 ; 结尾。
3.不允许把多个短语句写在一行中,即一行只写一条语句。
4.当一条语句一行写不下时,请考虑折行。在运算符号,最好是逗号后换行。
5.相对独立的程序块之间、变量说明之后加空行。
6.if、for、do、while、case、switch等语句自占一行,且if、for、do、while 等语句的执行体要加括号 {} ,即使只有一句。
7.函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格, case 语句下的情况处理语句也要遵从语句缩进要求。
8.一条有返回值的 return 语句不要使用“( )”(如: return (x);)来括住返回值。如果返回表达式,则表达式应与 return 关键字在同一行,以避免误加分号错误。
9.函数可先调用再声明,内部函数应在var声明内部变量的语句之后声明,可以清晰地表明内部变量和内部函数的作用域。
10.禁止重复脚本:包括JS文件和功能相同的函数。
代码优化及注意事项
1.尽量避免全局变量的使用。全局变量在引用时不得不一级一级查看作用域直到搜索到全局作用域,尤其在嵌套的调用很多的时候。并且全局变量将始终存在在脚本生命周期中,调用结束后无法被回收。
2.eval 是恶魔。eval 函数效率特别低,由于事先无法知晓传给 eval 的字符串中的内容,eval在其上下文中解释要处理的代码,也就是说编译器无法优化上下文,因此只能由浏览器在运行时解释代码,这对性能影响很大。避免使用它。
3.不要使用 Function 构造器。Function 构造函数比 eval 略好,因为使用此代码不会影响周围代码,但其速度仍很慢。可通过创建匿名函数来代替。
4.不要给 setTimeout 或者 setInterval 传递字符串参数。setTimeout() 和 setInterval() 方法近似于 eval,当然其低效率也和 eval 一样。 可用 function(){xxx} 代替。另外需要注意的是 timeout 或时间延迟可能并不准确。大多数浏览器无法提供1ms以下的延迟,可能会设置最小可能延迟,通常在10 和 100 ms之间。
5.禁止使用 with。尽管看起来挺方便,但 with 效率很低。with 结构又创建了一个作用域,以便使用变量时脚本引擎搜索。这本身只轻微的影响性能。但严重的是编译时不知道此作用域内容,因此编译器无法像对其他作用域(如函数产生的作用域)那样对之优化。可代替的方法是使用变量引用对象,然后使用变量访问对象属性。
6.减少使用 continue 和 break。
7.仅在函数内使用 this。
8.不要在影响性能的关键函数中使用 try-catch-finally。由于此函数比较特殊,且是在运行时动态创建动态销毁,有些浏览器对其的处理并不高效。把 catch 语句放在关键循环中将极大影响性能。如果可能,应在脚本中不频繁被调用的地方进行异常处理,或通过检查某种动作是否被支持来避免使用。
9.注意隐式对象转换。如果代码中常调用 literal 值的方法,你应考虑首先创建对象。因为每次调用 literal 值的方法时,都会隐式的用相同的值创建新的对象。同样的情况适用于字符串拼接。最好不要把两个string合并后赋于变量,而应该分别与变量合并。这在大部分浏览器中都更快,而且消耗更少的内存。
10.在关键函数中避免 for-in。for-in 常被误用,特别是简单的 for 循环更合适时。for-in 循环需要脚本引擎创建所有可枚举的属性列表,然后检查是否存在重复。因此for 循环无疑会更高效。11.基本运算符比函数调用更快。典型的应用包括push方法,及Math对象的方法。其效率低于直接赋值和运算。
12.DOM。通常主要有三种情况引起 DOM 运行速度变慢。第一就是执行大量 DOM 操作的脚本,如从获取的数据中建造新的 DOM 树。第二种情况是脚本引起太多的 reflow 或重绘。第三种情况是使用较慢的 DOM 节点定位方法。
针对以上三种情况,有以下几种解决办法:
一些建议
1. {} 和[]
使用 {} 代替 new Object()。使用 [] 代替 new Array() 。当成员名是一组有序的数字时使用数组来保存数据。当成员名是无规律的字符串或其他时使用对象来保存数据。
2. ,(逗号)操作符避免使用逗号操作符,除非在特定的 for 语句的控制部分(这不包括那些被用在对象定义,数组定义,var 语句,和参数列表中的逗号分隔符)。
3. 作用域在 JS 中块没有作用域。只有函数有作用域。不要使用块,除非在复合语句中。
4. 赋值表达式避免在 if 和 while 语句的条件部分进行赋值。
if (a = b) {
会与
if (a == b) {
产生混淆,避免这种不容易判断对错的结构。
或者,可以考虑引用()加以区别。
if ((a = b)) {
5. === 和 !== 操作符。
使用 === 和 !== 操作符会相对好点。== 和 != 操作符会进行类型强制转换。特别是不要将 == 用于与错值比较(false,null,undefined,“”,0,NaN)。
6. 令人迷惑的加号和减号。
小心在 + 后紧跟 + 或 ++。这种形式很容易仍人迷惑。应插入括号以便于理解。total = subtotal + +myInput.value;最好能写成
total = subtotal + (+myInput.value);
这样 + + 不会被误认为是 ++。