JavaScript Code Style Guide
文章目录
空格(Spacing)
缩进符(Soft Tab)
使用空格(Space),不是制表符(Tab)
空白(Whitespace)
在行末(the end of line)或者空白行(blank line),禁止留有空白符
注释符之后必须留一空格
//不留空格,不好
// 留空格,好!
/* 留空格,好! */
/*
* 留空格,好!
*/
圆括号的内侧不需要加空格
// 不好
function doSomething( paramA, paramB ) {}
// 好
function doSomething(paramA, paramB) {}
符号(Symbols)
一元操作符(如!
、++
)与操作数(operand)之间禁止留有空白
// 不好
i ++;
// 好
i++;
所有逗号和分号(,
和;
)之前禁止空格
// 不好
let a , b ;
// 好
let a, b;
分号;
作为语句终止符(statement terminator)时,禁止出现在行中
// 不好
let a = 0; let b;
// 好
let a = 0;
let b;
字面量定义对象属性时,冒号:
前面禁止空格,后面加空格
// 不好
let a = {
property : 0,
prop : "abc"
};
// 好
let a = {
property: 0,
prop: "abc"
};
?
和:
作三元条件符时,前后必须都留空格
// 不好
isBoolean?0:1;
// 好
isBoolean ? 0 : 1;
空的闭合符(如()
,[]
,{}
)内部禁止出现空格
// 不好
let a = { };
// 好
let a = {};
文件(Source File)
UTF-8
编码
文件尾部留一空行(New line)
注释(Comments)
单行注释(Single line)
单行注释,写在语句上方或右方
// 这里的注释用来解释下一行代码
doSomething(); // 行末注释
/* 这样也是可以的 */
thisIsOkToo();
多行注释(Multiline)
多行注释以/*
开头,*/
结尾,并且换行;所有星号对齐;开头和结尾禁止写注释
/*start
*不好
end*/
/*
* 好
*/
文档注释(Document)
文档注释以/**
开头,*/
结尾;和多行注释的区别在于会出现在API文档中,常用规范为jsDoc
/**
* 这是一个加法函数add
* @param {number} a - 甲数
* @param {number} b - 乙数
* @return {number} 甲乙之和
*/
function add(a, b) {
return a + b;
}
命名习惯(Naming Conventions)
命名法总结:
名称 | 示例 | 说明 | 常见用途 |
---|---|---|---|
(小)驼峰 | camelCase | 首字母小写,单词间隔大写 | 普通变量、函数 |
帕斯卡(大驼峰) | PascalCase | 首字母大写,单词间隔大写 | 类、构造函数 |
短横线 | kebab-case | 单词间隔短横线(- )连接 | HTML标签,CSS类,库、生产环境的js文件名 |
下划线 | SNAKE_CASE | 单词间隔下划线(_ )连接 | 特殊常量 |
匈牙利(HN) | g_arrTemp | 属性 + 类型 + 对象描述 | 正则表达式rIdCard |
变量(Variable)
普通变量强制使用驼峰命名,尽管有悖于日常写法
// 不好
const XMLHTTPRequest;
const personID;
const fetchURL;
// 好
const XmlHttpRequest;
const personId;
const fetchUrl;
重要常量可以全部大写,下划线连接;布尔变量尽量用is-
、has-
、can-
前缀命名
const MAX_COUNT = 65535;
let customValue = 0;
let isShowPage = true;
函数(Function)
普通函数驼峰命名,尽量以动词开头get-
,set-
等;构造函数(包括Class)以Pascal命名,即首字母大写;函数或类内部的私有属性可以加下划线(_
)开头,用以区分;事件处理回调函数可以handle-
前缀开头
function getFormData(){}
function Node(){}
class Element{
_privateProperty = 0;
}
function handleClick(){}
数组(Array)
目前来看,简单地加-s
,或者-List
、-Array
后缀都是可行的
// 都可以
let dogs = [];
let dogList = [];
let dogArray = [];
代码风格一致(Code Style Consistency)
我们允许“百家争鸣”的风格,但是在任何单个项目内必须保持统一
缩进长度(Indentation)
建议缩进采用二缩进,更节省横向视野
引号(Quotes)
建议字符串最外层使用双引号,兼容JSON
分支(Switch)
建议避免使用switch
,大多数时候if
完全够用了
行长(Column Line Length)
建议一行长度不超过80字符
分号(Semicolons)
建议永远使用分号结尾,不要迷信ASI
(Automatic semicolon insertion)
值得注意得是,function
声明、class
、if
、else
、for
、while
、try
等语句结束的花括号后不需要分号;
// 对象声明本质是赋值语句,结尾要加分号
var obj = {
name: 'Cambricon'
};
// 函数表达式本质是赋值语句,结尾要加分号
var add = function(a, b) {
return a + b;
};
// 函数声明不需要分号
function add(a, b) {
return a + b;
}
// for,if,else不需要分号
for(let i = 0; i < 10; i++) {
if(i > 5) {
console.log(i - 5);
} else {
console.log(i);
}
}
括号(Brace & Parenthese)
构造函数调用:永远使用括号调用
// 不好
new Date;
// 好
new Date();
if/else/for/while/try
等永远使用完整的圆括号、花括号
// 不好
if (value === "the value") doSomething();
// 好
if (value === "the value") {
doSomething();
}
箭头函数(Arrow Function)
建议单个参数的箭头函数不用带括号
// 不好
let lowStr = (str) => str.toLowerCase();
// 好
let lowStr = str => str.toLowerCase();
尾部逗号(Trailing Comma)
建议禁用尾部逗号,看起来很奇怪
// 不好
let object = {
propA: 12,
propB: "abc",
};
// 好
let object = {
propA: 12,
propB: "abc"
};
提前返回(Early Return)
建议提前返回,避免冗长
// 不好
function returnEarly( foo ) {
let result;
if ( foo ) {
result = "foo";
} else {
result = "quux";
}
return result;
}
// 好
function returnEarly( foo ) {
if ( foo ) {
return "foo";
}
return "quux";
}
强制类型转换(Coerced Type)
类型转换是不可避免的,掌握语言的技巧简化代码
// 不好
let nextHour = new Date().getTime() + 60 * 60 * 1000;
// 好
let nextHour = +new Date() + 60 * 60 * 1000;
提升(Hoisting)
var
、function
、import
都会提升,请尽可能地把它们放在(文件/代码)顶部;同时,尽量把export default
、module.exports
等放在文件尾部
// 不好
export default addOne;
function addOne(num) {
one = 1;
return num + one;
var one;
}
import xxx from "./xxx";
// 好
import xxx from "./xxx";
function addOne(num) {
var one = 1;
return num + one;
}
export default addOne;
扩展运算符(Spread Operator)
利用扩展运算符,代替旧的API,简化代码
const odds = [1, 3, 5, 7];
const evens = [2, 4, 6, 8];
/* join */
let nums = evens.concat(odds); // ES5
let nums = [...evens, ...odds]; // ES6+
/* clone */
let numsCopy = nums.slice(); // ES5
let numsCopy = [...nums]; // ES6+
严格等于(Strict Equality)
永远使用===
,只有一种例外:需要模糊判断null
和undefined
if(value == null) {
// value 可以是 null 或 undefined
}
类型检查(Type Checks)
检查String
、Number
、Boolean
、Object
时使用typeof
typeof object = 'number';
检查Array
时使用Array.isArray()
Array.isArray(object);
检查null
时使用object === null
检查undefined | null
时使用object == null
检查undefined
时,局部变量和对象属性使用object === undefined
;全局对象使用typeof
typeof object === 'undefined'; // 全局
object.prop === undefined; // 局部
属性存在性(Property Existence)
判断对象是否具有某个属性:in
和hasOwnProperty
"prop" in object; // 包含原型属性
object.hasOwnProperty(prop); // 只含自身属性
简写(Shorthand)
每个变量都要写很长的名字是教条主义,下面列出一些在业内得到广泛认可的简写。简写可以使代码更简洁,这一点在匿名回调函数中尤为有用。
简写 | 全写 | 用途 |
---|---|---|
a/acc | accumulator | 累加值 |
a/arg/argv | argument value | 参数 |
c/cv/cur | current value | 当前值 |
cb | callback | 回调 |
e/el/ele | element | 元素 |
f/fn/fun/func | function | 函数 |
i/j/k/m/n | index | 遍历序数 |
init | initial | 初始化 |
l/len | length | 长度 |
src | source | 源 |
t/tmp | temporary | 临时 |
that/_this | this | 指代this上下文 |
v/val | value | 值 |
vm | view model | 常用于Vue中表示this,指代Vue实例 |
// 不好
array.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// 好
array.reduce((a, c) => a + c, 0);
延伸阅读(Further Reading)
本规范主要参考:jQuery Style
其他参考: