JavaScript编码风格指南(中文版)
前言:
程序语言的编码风格对于一个长期维护的软件非常重要,特别是在团队协作中。如果一个团队使用统一规范的编码分风格,可以提高团队的协作水平和工作效率。编程风格指南的核心是基本的格式化规则,这些规则决定了如何编写高水准的代码。本指南来自于《编写可维护的JavaScript》这本书,基于"Java语言编码规范"和Crockford的JavaScript编程规范,还有Nicbolas的一些个人经验和喜好。写作本文旨在加深自己印象,也为了更多人的了解到JS编码风格,提高自己的编码质量。想了解更多的内容请阅读《编写可维护的JavaScript》。
1.缩进
每一行的层级由4个空格组成,避免使用Tab进行缩进。
// 好的写法 if (true) { doSomeThing(); }
2.行的长度
每行长度不应超过80个字符。如果一行超过80个字符,应当在一个运算符后换行。下一行应当增加两级缩进(8个字符)。
// 好的写法 doSomeThing(argument1, argument2, aegument3, argument4, argument5); // 不好的写法:第二行只有4个空格的缩进 doSomeThing(argument1, argument2, aegument3, argument4, argument5);
3.原始值
字符串应当始终使用双引号且保持一行,避免在字符串中使用斜线另起一行。
数字应当使用十进制整数,科学计算法表示整数,十六进制整数,或者十进制浮点小数,小数前后应当至少保留一位数字。避免使用八进制直接量。
特殊值null除了下述情况下应当避免使用。
"htmlcode">
// 好的写法 for (var i = 0; i < count; i++) { process(i); } // 不好的写法:丢失了空格 for (var i=0; i<count; i++) { process(i); }
5.括号间距
当使用括号时,紧接左括号之后和紧接右括号之前不应该有空格。
// 好的写法 for (var i = 0; i < count; i++) { process(i); } // 不好的写法:参数两边有额外的空格 for (var i = 0; i < count; i++) { process( i ); }
6.对象直接量
对象直接量应当有如下格式。
"htmlcode">
// 好的写法 var object = { key1: value1, key2: value2, func: function() { // doSomeThing }, key3: value3 }; // 不好的写法:不恰当的缩进 var object = { key1: value1, key2: value2 }; // 不好的写法:函数体周围缺少空行 var object = { key1: value1, key2: value2, func: function() { // doSomeThing }, key3: value3 };
当对象字面量作为函数参数时,如果值是变量,起始花括号应当同函数名在同一行。所有其余先前列出的规则同样适用。
// 好的写法 doSomeThing({ key1: value1, key2: value2 }); // 不好的写法:所有代码在一行上 doSomeThing({ key1: value1, key2: value2 });
7.注释
使用简洁明了注释有助于他人理解你的代码。如下情况应当使用注释。
"htmlcode">
// 好的写法 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); } // 不好的写法:注释之前没有空行 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); } // 不好的写法:错误的缩进 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); } // 不好的写法:应当使用多行注释 // 这段代码进行**判断 // 然后执行 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); } // 好的写法:在行尾注释时,代码结尾和注释间应保留一个空格 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); // 执行**函数 } // 不好的写法:代码和注释间没有足够的空格 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed();// 执行**函数 } // 好的写法:在注释掉一个代码块时,应联系使用单行注释,多行注释不应当使用在此种情况下。 // if (condition) { // allowed();//执行**函数 // }
多行注释
多行注释应当在代码需要更多文字去解释的时候使用。每个多行注释都至少有如下三行:
1.首行仅仅包括/*注释开始。该行不应当有其他文字。
2.接下来的行以*开头并保持左对齐。这些可以有文字描述。
3.最后一行以*/开头并同先前行保持对齐。也不应有其他文字。
多行注释的首行应当保持同它描述代码的相同层次的缩进。后续的每行应当有同样层次的缩进并附加一个空格(为了适当保持*字符的对齐)。每一个多行代码之前应当预留一个空行。
// 好的写法、 if (condition) { /* * 如果代码执行到这里 * 说明通过了所有的安全检测 */ allowed(); }
注释声明
注释有时候也可以用来给一段代码声明额外的信息。这些声明的格式以单个单词打头并紧跟一个冒号。可以使用的声明如下。
TODO:说明代码还未完成。应当包含下一步要做的事情。
HACK:表明代码实现走了一个捷径。应当包含为何使用hack的原因。这也可能表明该问题可能会有更好的解决办法。
XXX:说明代码是有问题的并应当尽快修复。
FIXME:说明代码是有问题的并应尽快修复。重要性略次于XXX。
REVIEW:说明代码在任何可能的改动都需要评审。
这些声明可能在一行或者多行注释中使用,并且应当遵循同一般注释类型相同的格式规则。
8.命名
变量和函数在命名时应当小心。命名应紧限于数字字母字符,某些情况下可以使用下划线(_)。最好不要在任何命名中使用美元符号($)或者反斜杠(\)。
变量命名应当采用驼峰命名格式,首字母小写,每个单词首字母大写。变量名的第一个单词应当是一个名词(而非动词)以避免同函数混淆。不要在变量名中使用下划线。
// 好的写法 var accountNumber = "test001"; // 不好的写法:大写字母开头 var AccountNumber = "test001"; // 不好的写法:动词开头 var getAccountNumber = "test001"; // 不好的写法:使用下划线 var account_number = "test001";
函数名也应当采用驼峰命名格式。函数名的第一个单词应当是动词(而非名词)来避免同变量混淆。函数名中最好不要使用下划线。
// 好的写法 function doSomething() { // code } // 不好的写法:大写字母开头 function DoSomething() { // code } // 不好的写法:名词开头 function something() { // code } // 不好的写法:使用下划线 function do_something() { // code }
构造函数--通过new运算符创建新对象的函数--也应当以驼峰格式命名并且首字符大写。构造函数名称应当以非动词开头,因为new代表着创建一个对象实例的操作。
// 好的写法 function MyObject() { // code } // 不好的写法:小写字母开头 function myObject() { // code } // 不好的写法:使用下划线 function my_object() { // code } // 不好的写法:动词开头 function getMyObject() { // code }
常量(值不会被改变的变量)的命名应当是所有大写字母,不同单词之间单个下划线隔开。
// 好的写法 var TOTAL_COUNT = 10; // 不好的写法:驼峰形式 var totalCount = 10; // 不好的写法:混合形式 var total_COUNT = 10;
对象的属性同变量的命名规则相同。对象的方法同函数的命名规则相同。如果属性或者方法是私有的,应当在之前加上一个下划线。
// 好的写法 var object = { _count: 10,4 _getCount: function() { return this._count; } }
9.变量与函数声明
变量声明
所有的变量在使用前都应当事先定义。变量定义应当放在函数开头,使用一个var表达式每行一个变量。除了首行,所有行都应当多一层缩进以使变量名能够垂直方向对齐。变量定义时应当初始化,并且赋值操作符应当保持一致的缩进。初始化的变量应当在未初始化变量之前。
// 好的写法 var count = 10, name = "jeri", found = false, empty;
函数声明
函数应当在使用前提前定义。一个不是作为方法的函数(也就是说没有作为一个对象的属性)应当使用函数定义的格式(不是函数表达式和Function构造器格式)。函数名和开始圆括号之间不应当有空格。结束的圆括号和右边的花括号之间应当留一个空格。右侧的花括号应当同function关键字保持同一行。开始和结束括号之间不应该有空格。参数名之间应当在逗号之后保留一个空格。函数体应当保持一级缩进。
// 好的写法 function outer() { var count = 10, name = "jeri", found = false, empty; function inner() { // code } // 调用inner()的代码 }
匿名函数可能作为方法赋值给对象,或者作为其他函数的参数。function关键字同开始括号之间不应有空格。
// 好的写法 object.method = function() { // code }; // 不好的写法:不正确的空格 object.method = function () { // code };
立即被调用的函数应当在函数调用的外层用园括号包裹。
// 好的方法 var value = (function() { // 函数体 return { message:"hi" } }());
严格模式
严格模式应当仅限在函数内部使用,千万不要在全局使用。
// 不好的写法:全局使用严格模式 "use strict"; function doSomething() { // code } // 好的写法 function doSomething() { "use strict"; // code }
10.运算符
赋值
给变量赋值时,如果右侧是含有比较语句的表达式,需要用圆括号包裹。
// 好的写法 var flag = (i < count); // 不好的写法:遗漏圆括号 var flag = i < count;
等号运算符
使用===(严格相等)和!==(严格不相等)代替==(相等)和!=(不等)来避免弱类型转换错误。
// 好的写法 var same = (a === b); // 好的写法 var same = (a == b);
三元操作符
三元运算符应当仅仅用在条件赋值语句中,而不要作为if语句的替代品。
// 好的写法 var value = condition "htmlcode">// 好的写法 count++; a = b; // 不好的写法:多个表达式写在一行 count++; a = b;返回语句
返回语句当返回一个值的时候不应当使用圆括号包裹,除非在某些情况下这么做可以让返回值更容易理解。例如:
return; return collection.size(); return (size > 0 "htmlcode">if (condition) { statements } if (condition) { statements } else { statements } if (condition) { statements } else if (condition) { statements } else { statements }绝不允许在if语句中省略花括号。
// 好的写法 if (condition) { doSomething(); } // 不好的写法:不恰当的空格 if (condition){ doSomething(); } // 不好的写法:所有代码都在一行 if (condition) { doSomething(); } // 不好的写法:所有代码都在一行且没有花括号 if (condition) doSomething();for 语句
for类型的语句应当是下面的格式。
for (initialization; condition; update) { statements } for (variable in object) { statements }for语句的初始化部分不应当有变量声明。
// 好的方法 var i, len; for (i=0, len=0; i < len; i++) { // code } // 不好的写法:初始化时候声明变量 for (var i=0, len=0; i < len; i++) { // code } // 不好的写法:初始化时候声明变量 for (var prop in object) { // code }当使用for-in语句时,记得使用hasOwnProperty()进行双重检查来过滤对象的成员。
while 语句
while 类的语句应当是下面的格式。
while (condition) { statements }do 语句
do 类的语句应当是下面的格式。
do { statements } while (condition);switch 语句
switch 类的语句应当是如下格式。
switch (expression) { case expression: statements default: statements }switch下的第一个case都应当保持一个缩进。除第一个之外包括default在内的每一个case都应当在之前保持一个空行。
每一组语句(除了default)都应当以break、return、throw结尾,或者用一行注释表示跳过。
// 好的写法 switch (value) { case 1: /* falls through */ case 2: doSomething(); break; case 3: return true; default: throw new Error("Some error"); }如果一个switch语句不包含default情况,应当用一行注释代替。
// 好的写法 switch (value) { case 1: /* falls through */ case 2: doSomething(); break; case 3: return true; default: // 没有default }try 语句
try类的语句应当格式如下。
try { statements } catch (variable) { statements } try { statements } catch (variable) { statements } finally { statements }12.留白
在逻辑相关的代码之间添加空行代码可以提高代码的可读性。
两行空行仅限于在如下情况下使用:
""和‘'的使用,我们也不必都使用"",使用''也是可以的,只要保持一致的风格就可以了。还有很多其他类似的风格问题,全凭个人选择。没有绝对的准则,只有适不适合。
下一篇:JavaScript使用forEach()与jQuery使用each遍历数组时return false 的区别
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?