前言
个人认为编码规范是很重要的,它可以达到提高代码质量,增强团队的开发协作的目的.
作为强迫症患者,如果看到不符规范的代码,我会十分难受.
以下规范主要根据书籍 Maintainable Javscript 翻译而来, 结合其他资料,根据个人喜好,有改动.
缩进
缩进使用2个或4个空格, 具体选哪个, 与团队约定好即可.
本文的缩进是4个空格的
不要使用tab
, 更不要空格与tab
混合使用
1 2 3 4
| if (true) { doSomething(); }
|
不使用tab
的原因是,目前还没有确定的规范说tab
代表了几个空格,你当然可以设置,但该设置也许换个编辑器就失效了(我就吃过这种苦头), 更别说换一台电脑打开了.
换行
单行最好不超过80个字符,当然也不用真的去数,当编辑器出现横向的滚动条时,就果然换行吧.
操作符放在行尾,如逗号,加号等.
续行要比正常的代码多一个级别的缩进
1 2 3 4 5 6 7 8 9 10 11
| doSomething(argument1, argument2, argument3, argument4, argument5);
doSomething(argument1, argument2, argument3, argument4, argument5);
doSomething(argument1, argument2, argument3, argument4 , argument5);
|
命名
命名是机算机界两大难题之一
变量
变量应该遵循以下规则:
- 驼峰命名
- 名词开头
- 尽量不要带$, 除非是类似
jQuery
查询返回的对象
- 尽量不要用下划线, 除非你在用
underscore
或loadash
1 2 3 4 5 6 7 8 9 10 11
| var accountNumber = "8401-1";
var AccountNumber = "8401-1";
var getAccountNumber = "8401-1";
var account_number = "8401-1";
|
函数的名字以动词开头, 其余规则同变量命名规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function doSomething() { }
function DoSomething() { }
function car() { }
function do_something() { }
|
常量使用const
关键字,字母全部大写,单词之前使用下划线分割
1 2 3 4 5 6 7 8
| var TOTAL_COUNT = 10;
var totalCount = 10;
var total_COUNT = 10;
|
对象的私有属性/私有方法,以下划线开头
1 2 3 4 5 6 7 8
| var object = { _count: 10, _getCount: function () { return this._count; } };
|
文件
一般文件名 推荐单词全部小写, 多个单词以中划线分割
JSX
文件名则使用首字母也大写的驼峰命名规则,不使用分割符
文件夹命名规则 推荐同一般文件名
路径(url)
有时需要js来定制路由规则, 则此时就涉及到url的命名
参考
google
https://developer.chrome.com/multidevice/webview/gettingstarted
以及facebook
https://facebook.github.io/react/blog/2016/07/22/create-apps-with-no-configuration.html
我推荐url命名也全部单词小写, 多个单词以中划线分割
操作符
操作符两边要有一个空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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); }
|
判断相等
尽量使用 === and !== 替代 == and != 避免发生类型转换
1 2 3 4 5
| var same = (a === b);
var same = (a == b);
|
三元表达式
一般而言, 三元素表达式用来简化赋值操作, 而不是为了简化if-else
1 2 3 4 5 6 7 8
| var value = condition ? value1 : value2;
condition ? doSomething() : doSomethingElse();
return (size > 0 ? size : defaultSize);
|
特殊情况:
在JSX
中, 为了方便, 我经常会用第二种写法, 我觉得也是可以接受的, 但也仅限于JSX
基本类型
字符串
字符串变量建议使用单引号,考虑到html的元素的属性是双引号的,使用单绰号可以方便写出下面的代码:
1 2
| document.body.innerHTML = '<div class="alert" role="alert">你的浏览器实在<strong>太太太太太太旧了</strong></div>';
|
字符串最好用一行来表示,不要使用反斜杠在新的一行创建字符串
1 2 3
| var longString = 'Here's the story, of a man \ named Brady.';
|
如果真的要多行, 请使用ES6的模板字符串
模板字符串的另一个好处是, 字符串里可以使用变量, 因此也不再需要使用加号来拼接字符串.
1 2 3 4
| var name = 'Bob', time = 'today';
`Hello ${name}, how are you ${time}?`
|
数字
整数不要使用八进制(这个应该没人用吧)
1 2 3 4 5 6 7 8
| var count = 10;
var num = 0xA2;
var num = 1e23;
|
浮点数至少带有一个小数位(以js的机制而言,js里的数字全是浮点数,这里是指某一变量会存储带小数的数值)
1 2 3 4 5 6
| var price = 10.0; var price = 10.00;
var price = 10.;
|
下面是有争议的例子:
书中认为这种写法并不好.
但这种写法在CSS中是属于精简的/值得鼓励的.
考虑到写js的人也会写CSS, 我认为这种写法是可以接受的, 反正我喜欢这样写😁
null
null
值只用在以下四种情况中:
- 初始化一个将会存放对象的变量
- 检测一个变量是否在初始化时, 以对象赋值
- 检测函数的参数是否是对象
- 函数返回值期望是对象时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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
不要直接使用undefined
若要查看变量是否已定义, 可以使用typeof
关键字
1 2 3 4 5 6 7 8 9
| if (typeof variable === 'undefined') { }
if (variable == undefined) { }
|
typeof 后面不要加括号
对象
对象应该遵循以下规则:
- 张开的大括号应该与声明同行
- 闭合的大括号应该单独一行
- 每一对属性-值都应该在单独一行,且有一个级别的缩进
- 属性不用带引号, 后面紧跟着冒号, 冒号与值之前有一个空格
- 方法前后要有一行空行
- 相关的属性放到一起, 且后面添加额外的空行,以提高可读性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| var object = { key1: value1, key2: value2,
func: function() { },
key3: value3 };
var object = { key1: value1, key2: value2 };
var object = { key1: value1, key2: value2, func: function() { }, key3: value3 };
|
参考ES6编程风格
多行定义的对象,最后一个成员以逗号结尾。
1 2 3 4
| const b = { k1: v1, k2: v2, };
|
虽然编译器报警告, 但使用babel
(我使用的是6.3.17 (babel-core 6.3.26)版本)编译后, 最后的一个逗号是会去掉的.
函数传参为对象时:
1 2 3 4 5 6 7 8
| doSomething({ key1: value1, key2: value2 });
doSomething({key1: value1, key2: value2});
|
如果对象只有一个键值对, 写在一行可以接受:
doSomething({key: value1});
变量声明
所有变量应该声明后使用
同时对多个变量声明,只使用一个var, 一行一个变量; 除了第一行,均使用一个级别的缩进
有初始化的的变量在无初始化的前面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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 count = 10, name = "Nicholas";
var found = false, empty;
|
注:
ES6的let与const的出现,完全可以取代var
. 不是直接在浏览器里写js的话,尽量避免var
的使用
原文中认为 = 要对齐, 我认为没必要,因为这样极有可能要填充许多空格:
1 2 3 4
| var count = 10, longName = "Nicholas", found = false,
|
函数声明
函数先声明后使用
使用函数声明,而不是函数表达式,也不要使用函数构造器
函数体的大括号应该与function
关键字同一行; 与包含参数的右括号有一个空格
多个参数时,后一个参数与前面的逗号要有一个空格
函数体的代码要有一个级别的缩进
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function doSomething(arg1, arg2) { return arg1 + arg2; }
function doSomething (arg1, arg2){ return arg1 + arg2; }
function doSomething(arg1, arg2) { return arg1 + arg2; }
var doSomething = function(arg1, arg2) { return arg1 + arg2; };
var doSomething = new Function("arg1", "arg2", "return arg1 + arg2");
|
函数里面既有变量声明又有函数声明时, 内部函数的声明应在变量之后.
内部变量的声明最好与外部函数的声明有一行空行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function outer() { var count = 10, name = "Nicholas";
function inner() { }
}
function outer() {
function inner() { }
var count = 10, name = "Nicholas";
}
|
匿名函数赋值为对象的方法时,fuction
关键字与左括号不应该有空格
1 2 3 4 5 6 7 8 9
| object.method = function() { };
object.method = function () { };
|
立即执行函数应该用括号把整个函数的调用包起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| var value = (function() {
return { message: "Hi" } }());
var value = function() {
return { message: "Hi" } }();
var value = (function() {
return { message: "Hi" } })();
|
在写React组件时, 推荐组件生命周期函数在前, 事件处理等helper函数在后
如果是ES6
写法, 定义函数时推荐使用箭头函数, 不要手动绑定this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| clss Component extends React.Component { static defaultProps = { } constructor(props) { super(props) this.state = { } } componentWillMount() { } componentDidMount() { } componentWillReceiveProps(props) { } componentDidUpdate() { } render() { } onClick = e => { } helpRender = () => { } }
|