为什么编码规范如此重要?
软件生命周期中80%的成本消耗在了维护上。
几乎所有的软件维护者都不是它的最初作者。
编码规范提高了软件的可读性,它让工程师能够快速且充分地理解新的代码。
如果你将源码作为产品来发布,你需要确保它是可完整打包的,且像你创建的其他产品一样整洁。
摘自:《Java语言编码规范》
基本的格式化
1.1 缩进层级
使用4个空格字符的缩进
1.2 语句结尾
JavaScript的分析器中存在一个叫作:自动分号插入(Automatic Semicolon Insertio, ASI) 的机制,使得JavaScript在代码省略分号的时候也可以正常工作。
总是使用分号
1.3 行的长度
长度限定在80个字符
1.4 换行
在运算符后换行,第二行追加两个缩进
例外情况:当给变量赋值时,第二行的位置应当和赋值运算符的位置保持对齐。
var result = one + two + three +
four + five;
1.5 空行
在方法之间
在方法中的局部变量和第一条语句之间
在多行或单行注释之前
在方法内的逻辑片段之间插入空行,提高可读性
1.6 命名
采用小驼峰
1.6.1 变量和函数
变量名应当总是遵守驼峰大小写命名法,并且命名前缀应当是名词
尽量在变量名中体现出值的数据类型。比如,命名count, length, size表明数据类型是数字,name, title, message表明数据类型是字符串。
常见动词约定
can |
函数返回一个布尔值 |
has |
函数返回一个布尔值 |
is |
函数返回一个布尔值 |
get |
函数返回一个非布尔值 |
set |
函数用来保存一个值 |
1.6.2 常量
使用大写字母和下划线
1.6.3 构造函数
使用大驼峰命名法
命名常用名词
1.7 直接量
1.7.1 字符串
使用单引号来括住字符串
多行字符串用字符串连字符(+)将字符串分成多行
1.7.2 数字
使用常用的格式
1.7.3 null
友情提醒:null有很多坑,使用过程中请注意
null是个特殊值,很容易跟undefined搞混
在下列情况下使用null
用来初始化一个变量,这个变量可能赋值为一个对象
用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象
当函数的参数期望是对象时,用作参数传入
当函数的返回值期望是对象时,用作返回值传出
下列情况下不要使用null
不要使用null来检测是否传入了某个参数
不要用null来检测一个未初始化的变量
1.7.4 undefined
友情提醒:undefined也有很多坑,使用过程中请注意
//pass
1.7.5 对象直接量
在直接量中直接写出所有属性
结束使用分号
1.7.6 数组直接量
使用方括号初始化
注释
2.1 单行注释
独占一行的注释,用来解释下一行代码。这行注释之前使用一个空行,且缩进层级和下一级代码保持一致
在代码行的尾部的注释。代码结束到注释之间至少有一个缩进。如果超过了最大字符数限制,就将这条注释放置于当前代码行的上方
被注释掉的大段代码
2.2 多行注释
/*
* example
* 例子
*/
2.3 使用注释
一般原则:在需要让代码变得更清晰时添加注释
2.3.1 难于理解的代码
//pass
2.3.2 可能被误认为错误的代码
当代码看上去有错误时
while (element && (element = element[axis])) { // 提示:赋值操作
//pass
}
2.3.3 浏览器hack
解释一下为什么要这样子hack
2.4 文档注释
使用JavaDoc风格
/**
相关描述
@method 方法名
@param {object} 被合并的一个或者多个对象
@return {object} 一个新的合并后的对象
**/
语句和表达式
块语句总是使用花括号
3.1 花括号对齐方式
if (condition) {
doSomeThing();
} else {
doSomeThingElse();
}
3.2 块语句间隔
在左圆括号之前和右圆括号之后各添加一个空格。
3.3 switch语句
3.3.1 缩进
使用Java风格
switch (condition) {
case: 'first':
// doSomeThing();
break;
case: 'second':
// doSomeThing();
break;
default:
// doSomeThing();
}
3.3.2 case语句的连续执行
switch (condition) {
case: 'first':
case: 'third':
// doSomeThing();
break;
case: 'second':
// doSomeThing();
break;
default:
// doSomeThing();
}
3.3.3 default
如果default没有行为,省略之
3.4 with
//pass
3.5 for
使用条件语句跳过循环
for (var i = 0; i < 10; i++) {
if (i != 2) {
process(values[i])
}
}
3.6 for-in
所有for-in都必须使用hasOwnProperty(),以避免遍历从原型继承来的属性
变量、函数和运算符
4.1 变量声明
所有变量声明放在函数顶部,且将var语句合并成一句,每个变量的初始化独占一行
4.2 函数声明
// pass
4.3 函数调用间隔
在函数名和左括号之间没有空格
4.4 立即调用的函数
在代码段的起始用括号括起来,再用一对圆括号来立即执行
4.5 严格模式
不要在全局中使用严格模式
4.6 相等
使用===和!==
4.6.1 eval()
只允许在将Ajax的返回值转为JavaScript的时候使用
4.6.2 原始包装类型
禁止使用
避免使用全局变量
5.1 单全局变量
创建一个唯一的全局对象名,并将所有的功能都挂载到这个全局对象上。
5.1.1 命名空间
var Steve = {};
Steve.work = {};
Steve.life = {};
Steve.study = {};
5.1.2 模块
使用RequireJS
事件处理
6.1 不好的典型用法实例
function handleClick(event) {
var popup = document.getElementById('popup');
popup.style.left = event.clientX + 'px';
popup.style.top = event.clientY + 'px';
popup.className = 'reveal';
}
6.2 规则1: 隔离应用逻辑
将应用逻辑从所有事件处理程序中抽离出来
var App = {
handleClick: function(event) {
this.showPopup(event);
},
showPopup: function(event) {
var popup = document.getElementById('popup');
popup.style.left = event.clientX + 'px';
popup.style.top = event.clientY + 'px';
popup.className = 'reveal';
}
};
$(element).on('click', function(event) {
App.handleClick(event);
});
6.3 规则2: 不要分发事件对象
让事件处理程序来处理event对象,然后拿到所有需要的数据传给应用逻辑。
var App = {
handleClick: function(event) {
this.showPopup(event.clientX, event.clientY);
},
showPopup: function(x, y) {
var popup = document.getElementById('popup');
popup.style.left = x + 'px';
popup.style.top = y + 'px';
popup.className = 'reveal';
}
};
$(element).on('click', function(event) {
App.handleClick(event);
});
将配置数据从代码中分离出来
7.1 什么是配置数据
配置数据是应用中写死的值
配置数据是可发生改变的,而且可以在修改页面中展示的信息时,不去修改JavaScript代码
7.2 抽离配置数据
将config放入单独的文件
不是你的对象不要动
8.1 原则
不覆盖方法
不新增方法
不删除方法
8.2 基于对象的继承
// pass
8.3 基于类型的继承
在定义了构造函数的情况下,基于类型的继承是最合适的
首先,原型继承
然后,构造器继承
function Person(name) {
this.name = name;
}
function Author(name) {
Person.call(this, name);
}
Authon.prototype = new Person();
8.4 门脸模式(推荐)
8.5 判断对象是否存在
使用typeof运算符,判断myObj是否有定义
if (typeof myObj == "undefined") {
var myObj = { };
}
本文严重依赖:《编写可维护的javascript》
本文作者:网友 来源:CIOZJ
CIO之家 www.ciozj.com 微信公众号:imciow