基本的风格化
- 缩进
4个空格 - 行结尾
必须以;结尾 - 行长度
以不超过100个字符为宜 - 换行
行超度超过100个字符,需要换行时,需要遵循以下规则:- 在运算符之后换行
- 第二行添加两个缩进
- 有一个第2条的例外,如果是赋值语句,为了程序可读性,第二行和第一行首个变量位置对齐
- 空行
空行应该添加的位置:- 方法和方法之间
- 函数内部局部变量和第一条语句之间
- 单行注释和多行注释前
- 函数内部逻辑区域之间(自行决定)
- 命名
- 变量和函数使用小驼峰标示(anotherVariable)
- 变量使用名词,函数使用动词,必须使用无意义的词
- 常量使用大写字母加下划线标示(MAX_COUNT)
- 构造函数使用大驼峰标示(PersonProfile),构造函数通常是名词
- 直接量
javascript包含字符串、数字、布尔值、null、undefined、对象、数组直接量- 字符串,使用单引号,html中使用双引号
- 字符串禁止使用多行方式,如果想使用多行,使用+运算符标示
- 浮点数不推荐使用10.和.1形式,这种不知道是故意没写,还是忘记写了
- 禁止使用八进制直接量,容易忽略且不常用
- null是用来初始化一个将来可能被赋值为对象的变量,null可以理解为对象的占位符
- 没有被初始化的变量的值为undefined,在代码中尽量避免使用undefined
注释
注释是为了更好地理解代码,在需要让代码变得更清晰的时候添加注释;也就是说在代码不够清晰时,才需要添加注释。应该使用注释的情况:
难以理解的代码
可能被误认为错误的代码,一般是非常规用法,比如while (element && (element = element[axis]))中,赋值运算用在条件判断中就很容易被理解为是===误写成了=,而编写者的原意就是赋值,这时候需要添加注释
浏览器特效hack(也可以认为是1,2的结合,既难理解,也会被误认为错误)
注释的种类
单行注释
单行注释的格式:- 独占一行的注释,用来解释下一行代码,注释之前有一个空行
- 在代码行尾部注释,代码和注释之间至少一个缩进
- //后面跟一个空格,// 这是一个注释
- 单行注释不应该以连续多行注释的形式出现,除非是你注释掉一大段代码
- 注释缩进应该和要解释的代码保持一致
多行注释
多行注释一般用于多行文本注释。格式如下:1
2
3
4/*
* 另一段注释
* 这段注释包含两行文本
*/不要用多行注释注释多行代码,因为这段代码中可能包含
*/
,比如正则表达式/a*/
或者代码中包含其他的多行注释。用单行注释来注释多行代码。文档注释
格式如下:1
2
3
4
5/**
* (description)
* @param {type} name description
* @return {type} name description
*/可以用jsDoc Toolkit或者YUIDoc生成根据你的文档注释生成注释文档,用于浏览所有注释的代码。
你应该对如下内容添加文档注释:
- 所有的方法
- 所有的构造函数
- 所有包含文档化方法的对象
语句和表达式
- 所有的块语句都应该使用花括号,无论是块语句是包含单行还是多行代码,避免造成误解。
花括号对齐方式:
1
2
3
4
5if (condition) {
} else {
}块语句间隔
- 首行前加一个空行。
- 在左圆括号之前和右圆括号之后各添加一个空格。
1
2
3if (condition) {
doSomething();
}
switch语句
缩进,case比switch多缩进一个层级,从第二个case开始,每个case前有一个空行
1
2
3
4
5
6
7
8
9
10
11switch (condition) {
case: "first":
// 代码
break;
case: "second":
// 代码
break;
default:
// 代码
break;
}case的连续执行
允许,但是要显示说明。
1
2
3
4
5
6
7
8
9
10
11switch (condition) {
case: "first":
// 代码
// fall through
case: "second":
// 代码
break;
default:
// 代码
break;
}default可以省略,写上注释
1
2
3
4
5
6
7
8
9switch (condition) {
case: "first":
// 代码
// fall through
case: "second":
// 代码
break;
// 没有default
}
with语句,禁止使用with语句,一是会造成困惑,而是会有性能问题
for循环,尽可能用条件语句代替continue语句,这样更容易理解
for-in循环
for-in循环用来遍历对象的属性,包括原型继承的属性,返回属性名。- 如果不是要故意查找原型链,for-in尽量总是使用hasOwnProperty
- for-in循环时用来遍历对象的,禁止用来遍历数组,可能会造成潜在的错误
变量、函数和运算符
- 变量
- 所有的变量声明放到函数顶部
- 使用单var语句, 未初始化的变量放到最后
- 变量声明语句和之后的逻辑语句中间空一行
函数
- 函数应该先声明后使用
- 函数声明紧接着变量声明
- 禁止在语句块内声明函数,不同的浏览器运行结果不一致
函数的调用间隔,左括号之前没有空格,和块语句区分
1
doSomething(item);
立即调用函数,用圆括号将函数包起来,这样看函数开头就可以识别出来这是一个立即调用表达式
1
2
3var value = (function() {
//代码
}());严格模式
- 禁止使用全局的”use strict”,这样如果是打包文件,其他文件和第三方文件很可能出错
- 函数尽量都是用严格模式
相等, 使用 === 和 !== , 禁止使用==和!=
禁止使用eval,禁止向Function、setTimeout、setInterval注入可执行字符串,如果实在要用,推荐使用eval()
原始包装类型
在javascript中你使用原始值(String、Boolean、Number),实际上是使用的原始包装对象,这是因为javascript引擎在背后调用了对于的原始类型构造函数包装该该初始值,所以你可以这样用:1
2var name = "Nicholas";
console.log(name.toUpperCase());有一点要注意,js引擎在遇到原始值时会自动创建这个原始值的原始包装对象,在执行完该语句时随即销毁,下次遇到再重新构建,所以你给一个字符串添加对象是读不到的:
1
2
3var name = "Nicholas";
name.author = true;
console.log(name.author); //undefined正是由于这个原因,在使用原始值和由原始类型构造函数创建出来的值是有区别的,而且使用原始类型构造函数创建原始值又繁琐,所以应该禁止使用String、Number和Boolean创建新对象。