本文详细阐述了 JavaScript 的编码规范,涵盖文件结构、缩进、注释、变量与函数声明、命名规则及语句格式。旨在通过统一的代码风格提升程序可读性、健壮性与可维护性,减少潜在错误,确保代码在长期生命周期中的高质量表现。
软件的核心价值源于其代码质量。在程序的全生命周期中,它可能被多位开发者阅读或修改。清晰展示代码结构与特征,能显著降低后续修改时的出错概率。遵循编程规范有助于提升程序的健壮性。
所有 JavaScript 代码均对公众可见,因此更需确保其质量。保持代码整洁至关重要。
JavaScript 文件
JavaScript 程序应独立保存于后缀为 .js 的文件中。
除非代码仅属于特定部分,否则不应将 JavaScript 代码嵌入 HTML 文件。嵌入代码会显著增加文件大小,且无法进行缓存和压缩。
filename.js 文件应尽量放置于 body 标签之后,以避免脚本加载延迟其他页面内容的载入。无需使用 language 或 type 属性,因为 MIME 类型由服务器决定,而非 script 标签。
缩进
缩进单位应为四个空格。应避免使用 Tab 键进行缩进(即便在 21 世纪),因为 Tab 长度缺乏统一标准。虽然使用空格会增加文件大小,但在局域网中影响可忽略,且在代码最小化过程中可被消除。
每行长度
避免每行超过 80 个字符。若单条语句无法一行写完,应考虑折行。建议在运算符或逗号后换行。在运算符后换行可降低因复制粘贴导致分号被掩盖的错误概率。下一行应缩进 8 个空格。
注释
不要吝啬使用注释。为未来阅读代码的人(包括未来的自己)留下信息非常有用。注释应与所注释的代码一样书写良好且清晰明了。适当的小幽默也是不错的,但需避免冗长或情绪化表达。
及时更新注释同样重要。错误的注释会使程序更难阅读和理解。
让注释具有实际意义,重点解释那些不易立即明白的逻辑。避免浪费读者时间阅读类似 的无效注释。
i = 0; //让i等于0
使用单行注释。块注释用于编写正式文档或注释掉无用代码。
变量声明
所有变量必须在使用前进行声明。虽然 JavaScript 不强制要求,但这能使程序更易读,并有助于发现未声明的变量(它们会被编译为全局变量)。
将 var 语句放在函数首部
最好将每个变量的声明语句单独放在一行,并添加注释说明。所有变量应按字母顺序排列。
var currentEntry; // 当前选择项 var level; // 缩进程度 var size; // 表格大小
JavaScript 没有块级作用域,因此在块内定义变量易引起 C/C++/Java 程序员的误解。应在函数首部定义所有变量。
尽量减少全局变量的使用,避免局部变量覆盖全局变量。
函数声明
所有函数在使用前进行声明。内部函数的声明应紧跟在 var 语句之后,这有助于判断哪些变量属于函数范围。
函数名与 ((左括号)之间不应有空格。((左括号)与开始程序体的 {(左大括号)之间应插入一个空格。函数体应缩进四个空格。}(右大括号)应与声明函数的那一行代码头部对齐。
function outer(c, d) { var e = c * d; function inner(a, b) { return (e * a) + b; } return inner(0, 1); }
这种书写方式在 JavaScript 中可正常使用,因为函数和对象的声明可置于任何允许表达式的地方。这种方式使内联函数和混合结构具有最佳可读性。
function getElementsByClassName(className) { var results = []; walkTheDOM(document.body, function (node) { var a; // 类名数组 var c = node.className; // 节点的类名 var i; // 循环计数器// If the node has a class name, then split it into a list of simple names.// If any of them match the requested name, then append the node to the set of results. if (c) { a = c.split(' '); for (i = 0; i < a.length; i += 1) { if (a[i] === className) { results.push(node); break; } } } }); return results; }
如果函数是匿名函数,则在 function 和 ((左括号)之间应有一个空格。若省略空格,可能让人误以为函数名叫作 function。
div.onclick = function (e) { return false; }; that = { method: function () { return this.datum; }, datum: 0 };
尽量不使用全局函数。
命名
变量名应由 26 个大小写字母 (A..Z, a..z)、10 个数字 (0..9) 和下划线 (_) 组成。避免使用国际化字符(如中文),因为它们并非在任何地方都能被方便地阅读和理解。不要在命名中使用 $(美元符号) 或反斜杠。
不要把下划线 (_) 作为变量名的第一个字符。它有时用于表示私有变量,但 JavaScript 并未提供私有变量功能。若私有变量很重要,应使用私有成员的形式。应避免这种易引起误解的命名习惯。
大多数变量名和方法名应以小写字母开头。
必须与 new 共同使用的构造函数名应以大写字母开头。当省略 new 时,JavaScript 不会抛出编译或运行错误。忘记加 new 可能导致不良后果(如被当作普通函数执行),因此大写构造函数名是避免此情况的唯一方法。
全局变量应全部大写。(JavaScript 没有宏或常量,因此不会造成误会)。
语句
简单语句
每一行最多只包含一条语句。将分号 (;) 放在每条简单语句的结尾。注意,函数赋值或对象赋值语句也是赋值语句,应以分号结尾。
JavaScript 可将任何表达式当作一条语句,这易隐藏错误,特别是误加分号的错误。仅在赋值和调用时,表达式才应被当作单独语句。
复合语句
复合语句是被包含在 {(左大括号)和 }(右大括号) 中的语句序列。
- 被括起的语句必须多缩进四个空格。
- {(左大括号)应在复合语句起始行的结尾处。
- }(右大括号)应与{(左大括号)的那一行的开头对齐。
- 大括号应在所有复合语句中使用,即使只有一条语句,当它们是控制结构(如 if 或 for 语句)的一部分时。这样做可避免后续添加语句时造成的错误。
标示
语句标示是可选的,只有以下语句必须被标示:while, do, for, switch。
return 语句
一条有返回值的 return 语句不要使用 () 括号来括住返回值。若返回表达式,则表达式应与 return 关键字在同一行,以避免误加分号错误。
if 语句
if 语句应如以下格式:
if (condition){ statements; } if (condition) { statements; } else { statements; } if (condition) { statements; } else if (condition) { statements; } else { statements; }
for 语句
for 语句应如以下格式:
for (initialization;condition ; update) { statements; } for (variable in object)if (filter) { statements; }
第一种形式的循环用于已知相关参数的数组循环。
第二种形式应用于对象中。object 原型中的成员将被包含在迭代器中。通过预先定义 hasOwnProperty 方法来区分真正的 object 成员是个不错的方法:
for (variablein object) if (object.hasOwnProperty(variable )){ statements; }
while 语句
while 语句应如以下格式:
while (condition){ statements; }
do 语句
do 语句应如以下格式:
do { statements; } while (condition);
不像其他复合语句,do 语句总是以分号 (;) 结尾。
switch 语句
switch 语句应如以下格式:
switch (expression){ case expression: statements; default: statements; }
每个 case 与 switch 对齐,这可避免过分缩进。
每一组 statements(除了 default)应以 break, return 或 throw 结尾,不要让它顺次往下执行。
try 语句
try 语句应如以下格式:
try { statements; } catch (variable){ statements; } try { statements; } catch (variable){ statements; } finally { statements; }
continue 语句
避免使用 continue 语句,它易使程序逻辑过程晦涩难懂。
with 语句
不要使用 with 语句。
空白
用空行将逻辑相关的代码块分割开,可提高程序的可读性。
空格应在以下情况时使用:
- 跟在 ((左括号) 后面的关键字应被一个空格隔开。例如:while (true) {
- 函数参数与 ((左括号) 之间不应有空格,这能帮助区分关键字和函数调用。
- 所有的二元操作符,除了 .(点)、((左括号) 和 [(左方括号),应用空格将其与操作数隔开。
- 一元操作符与其操作数之间不应有空格,除非操作符是个单词,比如 typeof。
- 每个在控制部分(如 for 语句)中的分号 (;) 后须跟一个空格。
- 每个逗号 (,) 后应跟一个空格。
另外的建议
{} 和[]
使用 {} 代替 new Object()。使用 [] 代替 new Array()。
当成员名是一组有序的数字时使用数组来保存数据。当成员名是无规律的字符串或其他时使用对象来保存数据。
,(逗号) 操作符
避免使用逗号操作符,除非在特定的 for 语句的控制部分。(这不包括那些被用在对象定义、数组定义、var 语句和参数列表中的逗号分隔符。)
作用域
在 JavaScript 中块没有作用域。只有函数有作用域。不要使用块,除非在复合语句中。
赋值表达式
避免在 if 和 while 语句的条件部分进行赋值。
if (a = b) {
是一条正确语句?或者
if (a == b) {
才是对的?避免这种不容易判断对错的结构。
===和!==操作符。
使用 === 和 !== 操作符会相对好点。== 和 != 操作符会进行类型强制转换。特别是,不要将 == 用于与错值(false, null, undefined, “”, 0, NaN)比较。
令人迷惑的加号和减号
小心在 + 后紧跟 + 或 ++。这种形式很容易令人迷惑。应插入括号以便于理解。
total = subtotal + +myInput.value;
最好能写成
total = subtotal + (+myInput.value);
,这样 + + 不会被误认为是 ++。
eval 是恶魔
eval 是 JavaScript 中最容易被滥用的方法。避免使用它。
eval 有别名。不要使用 Function 构造器。不要给 setTimeout 或者 setInterval 传递字符串参数。