JavaScript 编码风格指南
写作本文旨在加深自己印象,也为了更多人的了解到JS编码风格,提高自己的编码质量
想了解更多的内容请阅读《编写可维护的JavaScript》
缩进
- 每一行的层级由4个空格组成,避免使用制表符 (Tab) 进行缩进
// 好的写法 if (true) { doSomething(); }
行的长度
- 每行长度不应超过80个字符。如果一行超过80个字符,应当在一个运算符 (逗号, 加号等) 后换行。下一行应当增加两级缩进(8个字符)
// 好的写法 doSomething(argument1, argument2, aegument3, argument4, argument5); // 不好的写法:第二行只有4个空格的缩进 doSomething(argument1, argument2, aegument3, argument4, argument5); // 不好的写法:在运算符之前换行 doSomething(argument1, argument2, aegument3, argument4 , argument5);
原始值
- 字符串应当始终使用双引号 (避免使用单引号) 且保持一行,避免在字符串中使用斜线另起一行
个人建议: html 用双引号, js 用单引号; 反之, 亦可
// 好的写法 var name = "Nicholas"; // 不好的写法: 单引号 var name = 'Nicholas'; // 不好的写法: 字符串结束之前换行 var longString = "Here's the story, of a man \ named Brady.";
- 数字应当使用十进制整数,科学计算法表示整数,十六进制整数,或者十进制浮点小数,小数前后应当至少保留一位数字。避免使用八进制直接量
// 好的写法 var count = 10; // 好的写法 var price = 10.0; var price = 10.00; // 好的写法 var num = 0xA2; // 好的写法 var num = 1e23; // 不好的写法: 十进制数字以小数点结尾 var price = 10.; // 不好的写法: 十进制数字以小数点开头 var price = .1; // 不好的写法: 八进制 (base 8) 写法已废弃 var num = 010;
- 特殊值null除了下述情况下应当避免使用
- 用来初始化一个变量,这个变量可能被赋值为一个对象
- 用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象
- 当函数的参数期望是对象时,被用作参数传入
- 当函数的返回值期望是对象时,被用作返回值传出
// 好的写法 var person = null; // 好的写法 function getPerson() { if (condition) { return new Person("Nicholas"); } else { return null; } } // 好的写法 var person = getPerson(); if (person != null) { doSomething(); } // 不好的写法: 和一个未被初始化的变量比较 var person; if (person != null) { doSomething(); } // 不好的写法: 通过测试判断某个参数是否传递 function doSomething(arg1, arg2, arg3, arg4) { if (arg4 != null) { doSomethingElse(); } }
- 避免使用特殊值 undefined。判断一个变量是否定义应当使用 typeof 操作符
// 好的写法 if (typeof variable == "undefined") { // do something } // 不好的写法: 使用了 undefined 直接量 if (variable == undefined) { // do something }
运算符间距
- 二元运算符前后必须使用一个空格来保持表达式的整洁。操作符包括赋值运算符和逻辑运算符
// 好的写法 var found = (values[i] === item); // 好的写法 if (found && (count > 10)) { doSomething(); } // 好的写法 for (i = 0; i < count; i++) { process(i); } // 不好的写法: 丢失了空格 var found = (values[i]===item); // 不好的写法: 丢失了空格 if (found&&(count>10)) { doSomething(); } // 不好的写法: 丢失了空格 for (i=0; i<count; i++) { process(i); }
括号间距
- 当使用括号时,紧接左括号之后和紧接右括号之前不应该有空格
// 好的写法 var found = (values[i] === item); // 好的写法 if (found && (count > 10)) { doSomething(); } // 好的写法 for (i = 0; i < count; i++) { process(i); } // 不好的写法: 左括号之后有额外的空格 var found = ( values[i] === item); // 不好的写法: 右括号之前有额外的空格 if (found && (count > 10) ) { doSomething(); } // 不好的写法: 参数两边有额外的空格 for (i = 0; i < count; i++) { process( i ); }
对象直接量
- 对象直接量应当有如下格式
- 起始左花括号应当同表达式保持同一行
- 每个属性的名值对应当保持一个缩进,第一个属性应当在左花括号后另起一行
- 每个属性的名值对应当使用不含引号的属性名,其后紧跟一个冒号(之前不含空格),而后是值
- 倘若属性值是函数类型,函数体应当在属性名之下另起一行,而且其前后均应保留一个空行
- 一组相关的属性前后可以插入空行以提升代码的可读性
- 结束的右花括号应当独占一行
// 好的写法 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 });
注释
- 频繁地使用注释有助于他人理解你的代码。如下情况应当使用注释
- 代码晦涩难懂
- 可能被误认为错误的代码
- 必要但不明显的针对特定浏览器的代码
- 对于对象、方法或者属性,生成文档是有必要的(使用恰当的文档注释)
单行注释
- 单行注释应当用来说明一行代码或者一组相关的代码。单行注释可能有三种使用方式
- 独占一行的注释,用来解释下一行代码
- 在代码行的尾部的注释,用来解释它之前的代码
- 多行,用来注释掉一个代码块
// 好的写法 if (condition) { // 如果代码执行到这里,则表明通过了所有安全性检查 allowed(); } // 不好的写法:注释之前没有空行 if (condition) { // 如果代码执行到这里,则表明通过了所有安全性检查 allowed(); } // 不好的写法:错误的缩进 if (condition) { // 如果代码执行到这里,则表明通过了所有安全性检查 allowed(); } // 不好的写法:这里应当使用多行注释 // 接下来的这段代码非常难,那么,让我详细的解释一下 // 这段代码的作用氏首先判断条件是否为真 // 只有为真时才会执行。这里的条件是通过 // 多个函数计算出来的,在整个会话生命周期内 // 这个值氏可以被修改的 if (condition) { // 如果代码执行到这里,则表明通过了所有安全检查 allowed(); }
- 对于代码行尾单行注释的情况,应确保代码结尾同注释之间至少一个缩进
// 好的写法 var result = something + somethingElse; // somethingElse will never be null // 不好的写法: 代码和注释间没有足够的空格 var result = something + somethingElse;// somethingElse will never be null
- 注释一个代码块时在连续多行使用单行注释是唯一可以接受的情况.。多行注释不应当在这种情况下使用
// 好的写法 // if (condition) { // doSomething(); // }
多行注释
- 多行注释应当在代码需要更多文字去解释的时候使用。每个多行注释都至少有如下三行
- 首行仅仅包括
/*
注释开始。该行不应当有其他文字 - 接下来的行以
*
开头并保持左对齐。这些可以有文字描述 - 最后一行以
*/
开头并同先前行保持对齐。也不应有其他文字
- 首行仅仅包括
- 多行注释的首行应当保持同它描述代码的相同层次的缩进。后续的每行应当有同样层次的缩进并附加一个空格(为了适当保持
*
字符的对齐)。每一个多行代码之前应当预留一个空行
// 好的写法 if (condition) { /* * 如果代码执行到这里 * 说明通过了所有的安全检测 */ allowed(); } // 不好的写法: 注释之前无空行 if (condition) { /* * 如果代码执行到这里 * 说明通过了所有的安全检测 */ allowed(); } // 不好的写法: 星号后没有空格 if (condition) { /* *如果代码执行到这里 *说明通过了所有的安全检测 */ allowed(); } // 不好的写法: 错误的缩进 if (condition) { /* * 如果代码执行到这里 * 说明通过了所有的安全性检测 */ allowed(); } // 不好的写法: 代码尾部注释不要用多行注释格式 var result = something + somethingElse; /*somethingElse 不应当取值为null*/
声明
注释声明
- 注释有时候也可以用来给一段代码声明额外的信息。这些声明的格式以单个单词打头并紧跟一个冒号。可以使用的声明如下
- TODO
- 说明代码还未完成。应当包含下一步要做的事情
- HACK
- 表明代码实现走了一个捷径。应当包含为何使用 hack 的原因。这也可能表明该问题可能会有更好的解决办法
- XXX
- 说明代码是有问题的并应当尽快修复
- FIXME
- 说明代码是有问题的并应尽快修复。重要性略次于XXX
- REVIEW
- 说明代码在任何可能的改动都需要评审
- TODO
- 这些声明可能在一行或者多行注释中使用,并且应当遵循同一般注释类型相同的格式规则
// 好的写法 // TODO: 我希望找到一种更快的方式 doSomething(); // 好的写法 /* * HACK: 不得不针对 IE 做的特殊处理. 我计划后续有时间时 * 重写这部分. 这些代买可能需要在 v1.2 版本之前替换掉 */ if (document.all) { doSomething(); } // 好的写法 // REVIEW: 有更好的方法吗? if (document.all) { doSomething(); } // 不好的写法: 注释声明空格不正确 // TODO : 我希望找到一种更快的方式 doSomething(); // 不好的写法: 代码和注释应当保持同样的缩进 // REVIEW: 有更好的方法吗? if (document.all) { doSomething(); }
变量声明
- 所有的变量在使用前都应当事先定义。变量定义应当放在函数开头,使用一个 var 表达式每行一个变量。除了首行,所有行都应当多一层缩进以使变量名能够垂直方向对齐。变量定义时应当初始化,并且赋值操作符应当爆出一致的缩进。初始化的变量应当在未初始化变量之前
// 好的写法 var count = 10, name = "Nicholas", found = false, empty; // 不好的写法: 不恰当的初始化赋值 var count = 10, name = "Nicholas", found= false, empty; // 不好的写法: 错误的缩进 var count = 10, name = "Nicholas", found = false, empty; // 不好的写法: 多个定义写在一行 var count = 10, name = "Nicholas", found = false, empty; // 不好的写法: 未初始化的变量放在最前面 var empty, count = 10, name = "Nicholas", found = false; // 不好的写法: 多个 var 表达式 var count = 10, name = "Nicholas"; var found = false, empty;
函数声明
- 函数应当在使用前提前定义。一个不是作为方法的函数(也就是说没有作为一个对象的属性)应当使用函数定义的格式(不是函数表达式和 Function 构造器格式)。函数名和开始圆括号之间不应当有空格。结束的圆括号和右边的花括号之间应该留一个空格。右侧的花括号应当同 function 关键字保持同一行。开始和结束括号之间不应该有空格。参数名之间应当在都好之后保留一个空格。函数体应当保持一级缩进。
// 好的写法 function doSomething(arg1, arg2) { return arg1 + arg2; } // 不好的写法: 第一行不恰当的空格 function doSomething (arg1, arg2) { return arg1 + arg2; } // 不好的写法: 函数表达式 var doSomething = function doSomething(arg1, arg2) { return arg1 + arg2; } // 不好的写法: 左侧的花括号位置不对 function doSomething(arg1, arg2) { return arg1 + arg2; } // 错误的写法: 使用了 Function 构造器 var doSomething = new Function("arg1", "arg2", "return arg1 + arg2")
- 其他函数内部定义的函数应当在 var 语句后立即定义
// 好的写法 function outer() { var count = 10, name = "Nicholas", found = false, empty; function inner() { // 代码 } // 调用 inner() 的代码 } // 不好的写法: inner 函数的定义先于变量 function outer() { function inner() { // 代码 } var count = 10, name = "Nicholas", found = false, empty; // 调用 inner() 的代码 }
- 匿名函数可能作为方法赋值给对象,或者作为其他函数的参数。function 关键字同开始括号之间不应有空格
// 好的写法 object.method = function() { // 代码 }; // 不好的写法: 不正确的空格 object.method = function () { // 代码 };
- 立即被调用的函数应当在行数调用的外层用圆括号包裹
// 好的写法 var value = (function() { // 函数体 return { message: "Hi" } }()); // 不好的写法: 函数调用外层没有用圆括号包裹 var value = function() { // 函数体 return { message: "Hi" } }(); // 不好的写法: 圆括号位置不当 var value = (function() { // 函数体 return { message: "Hi" } })();
赋值
- 给变量赋值时,如果右侧是含有比较语句的表达式,需要用圆括号包裹
// 好的写法 var flag = (i < count); // 不好的写法:遗漏圆括号 var flag = i < count;
命名
- 变量和函数在命名时应当小心。命名应仅限于数字字母字符,某些情况下可以使用下划线。最好不要在任何命名中使用美元符号($)或者反斜杠(\)
- 变量命名应当采用驼峰命名格式,首字母小写,每个单词首字母大写。变量名的第一个单词应当是一个名词 (而非动词) 以避免同函数混淆。不要在变量名中使用下划线
// 好的写法 var accountNumber = "2312"; // 不好的写法:大写字母开头 var AccountNumber = "2312"; // 不好的写法:动词开头 var getAccountNumber = "2312"; // 不好的写法:使用下划线 var account_number = "2312";
- 函数名也应当采用驼峰命名格式。函数名的第一个单词应当是动词(而非名词)来避免同变量混淆。函数名中最好不要使用下划线
// 好的写法 function doSomething() { // 代码 } // 不好的写法:大写字母开头 function DoSomething() { // 代码 } // 不好的写法:名词开头 function something() { // 代码 } // 不好的写法:使用下划线 function do_something() { // 代码 }
- 这里有一些使用动词常见的约定
动词 | 含义 |
---|---|
can | 函数返回一个布尔值 |
has | 函数返回一个布尔值 |
is | 函数返回一个布尔值 |
get | 函数返回一个非布尔值 |
set | 函数用来保存一个值 |
if (isEnabled()) { setName("Nicholas"); } if (getName() === "Nicholas") { doSomething(); }
- 构造函数——通过new运算符创建新对象的函数——也应当以驼峰格式命名并且首字符大写。构造函数名称应当以非动词开头,因为new代表着创建一个对象实例的操作
// 好的写法 function MyObject() { // 代码 } // 不好的写法:小写字母开头 function myObject() { // 代码 } // 不好的写法:使用下划线 function my_object() { // 代码 } // 不好的写法:动词开头 function getMyObject() { // 代码 }
- 常量(值不会被改变的变量)的命名应当是所有大写字母,不同单词之间单个下划线隔开
// 好的写法 var TOTAL_COUNT = 10; // 不好的写法:驼峰形式 var totalCount = 10; // 不好的写法:混合形式 var total_COUNT = 10;
- 对象的属性同变量的命名规则相同。对象的方法同函数的命名规则相同。如果属性或者方法是私有的,应当在之前加上一个下划线
// 好的写法 var object = { _count: 10, _getCount: function() { return this._count; } }
严格模式
- 严格模式应当仅限在函数内部使用,千万不要在全局使用
// 不好的写法:全局使用严格模式 "use strict"; function doSomething() { // 代码 } // 好的写法 function doSomething() { "use strict"; // 代码 }
- 如果你期望在多个函数中使用严格模式而不需要多次声明“use strict”,可以使用立即被调用的函数
// 好的写法 (function() { "use strict"; function doSomething() { // 代码 } function doSomethingElse() { // 代码 } }());
运算符
等号运算符
- 使用===(严格相等)和!==(严格不相等)代替==(相等)和!=(不等)来避免弱类型转换错误
// 好的写法 var same = (a === b); // 好的写法 var same = (a == b);
三元运算符
- 三元运算符应当仅仅用在条件赋值语句中,而不要作为if语句的替代品
// 好的写法 var value = condition ? value1 : value2; // 不好的写法: 没有赋值, 应当使用 if 表达式 condition ? doSomething() : doSomethingElse;
语句
简单语句
- 每一行最多只包含一条语句。所有简单的语句都应该以分号(;)结束
// 好的写法 count++; a = b; // 不好的写法:多个表达式写在一行 count++; a = b;
- 返回语句
- 返回语句当返回一个值的时候不应当使用圆括号包裹,除非在某些情况下这么做可以让返回值更容易理解。例如
return; return collection.size(); return (size > 0 ? size : defaultSize);
复合语句
- 复合语句是大括号括起来的语句列表
- 括起来的语句应当较复合语句多缩进一个层级
- 开始的大括号应当在复合语句所在行的末尾;结束的大括号应当独占一行且同复合语句的开始保持同样的缩进
- 当语句是控制结构的一部分时,诸如 if 或者 for 语句,所有语句都需要用大括号括起来,也包括单个语句。这个约定使得我们更方便地添加语句而不用担心忘记加括号而引起 bug
- 像 if 一样的语句开始的关键词,其后应该紧跟一个空格,起始大括号应当在空格之后
if 语句
- if 语句应当是下面的格式
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(); } // 不好的写法:所有代码都在一行且没有花括号 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++) { // 代码 } // 不好的写法:初始化时候声明变量 for (var i=0, len=0; i < len; i++) { // 代码 } // 不好的写法:初始化时候声明变量 for (var prop in object) { // 代码 }
- 当使用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 }
留白
- 在逻辑相关的代码之间添加空行代码可以提高代码的可读性
- 两行空行仅限于在如下情况下使用
- 在不同的源代码文件之间
- 在类和接口定义之间
- 单行空行仅限在如下情况中使用
- 方法之间
- 方法中局部变量和第一行语句之间
- 多行或者单行注释之前
- 方法中逻辑代码块之间以提升代码的可读性
- 空格应当在如下的情况下使用
- 关键词后跟括号的情况应当用空格隔开
- 参数列表中逗号之后应当保留一个空格
- 所有的除了点(.)之外的二元运算符,其操作数都应当用空格隔开。单目运算符的操作数之间不应该用空白隔开,例如一元减号,递增(++),递减(--)
- for 语句的表达式之间应当用空格隔开
注意
- 切勿使用像 String 一类的原始包装类型创建新的对象
- 避免使用 eval()
- 避免使用with语句。该语句在严格模式中不复存在,可能在未来的ECMAScript 标准中也将去除
最后
- 上述指南并不是在开发过程中必须完全遵守的 (比如说引号和缩进等),我们可以只汲取其中的一部分来改善自己的编码风格,让自己的代码易读、可维护。关于编码风格,每个团队都有自己的特色,只要保持团队一致性,可以高效的开发就OK了
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
九道前端面试题及答案,妹子总结的
1、什么是W3C标准? WEB标准不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。 2、bootstrap响应式原理 是通过栅格系统和媒体查询实现的 // 小屏幕(平板,大于等于 768px)@media (min-width: @screen-sm-min) { ... }// 中等屏幕(桌面显示器,大于等于 992px)@media (min-width: @screen-md-min) { ... }// 大屏幕(大桌面显示器,大于等于 1200... 3、HTML/XHTM的区别 XHTML 与 HTML 4.01 标准没有太多的不同。 XHTML 元素必须被正确地嵌套。 XHTML 元素必须被关闭。 标签名必须用小写字母。 XHTML 文档必须拥有根元素。 4、页面构架和布局 布局可以是编码方面的,也可以是视觉方面的。...
- 下一篇
滑向未来(现代 JS 与 CSS 滚动实现指南)
一些(网站)滚动的效果是如此令人着迷但你却不知该如何实现,本文将为你揭开它们的神秘面纱。我们将基于最新的技术与规范为你介绍最新的 JavaScript 与 CSS 特性,(当你付诸实践时,)将使你的页面滚动更平滑、美观且性能更好。 大多数的网页的内容都无法在一屏内全部展现,因而(页面)滚动对于用户而言是必不可少的。对于前端工程师与 UX 设计师而言,跨浏览器提供良好的滚动体验,同时符合设计(要求),无疑是一个挑战。尽管 web 标准的发展速度远超从前,但代码的实现往往是落后的。下文将为你介绍一些常见的关于滚动的案例,检查一下你所用的解决方案是否被更优雅的方案所代替。 消逝的滚动条 在过去的三十年里,滚动条的外观不断改变以符合设计的趋势,设计师们为(滚动条的)颜色、阴影、上下箭头的形状与边框的圆角实验了多种风格。以下是 Windows 上的变化历程: (Windows 上的滚动条) 在2011年,苹果设计师从 ios 上获得灵感,为如何定义“美观的”滚动条确定了方向。所有滚动条均从 Mac 电脑中消失,不再占据任何页面空间,只有在用户触发滚动时(滚动条)才会重新出现(有些用户会设置不隐藏...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7设置SWAP分区,小内存服务器的救世主