前端代码相关规范
总结一下目前在用的前端代码规范,可作为开发参考
一、基础规范
开发规范
项目目录和文件的命名使用小写字母,避免使用大写或驼峰,多个单词以下划线 _ 分隔 如:my_project/cast_detail.js
目录有复数意义的时候,使用复数命名 如 scripts images
某些第三方插件可直接使用中划线 - 作为文件名单词的间隔 如 bootstrap-datepicker
某些特殊文件可以使用点号 . 作为文件名单词的间隔 如 webpack.config.dev.js jquery.cookie.min.js
使用有意义的英文单词式命名,避免使用拼音式(如 tupian.png )命名
编辑器设置文件保存格式为 utf-8,以四个空格作为缩进(包括HTML,CSS,JS等),文件末尾空一行,行尾去掉空格
单个函数行数,以不超过一个屏幕为宜(50行左右),超出一个屏幕的,就要考虑拆分成更少的函数
每行代码量不要太长,要适当进行分行(自己也可以在编辑器设置超长自动换行)
在 sublime 中的配置
{
"default_encoding": "UTF-8",
"ensure_newline_at_eof_on_save": true,
"trim_trailing_white_space_on_save": true,
"tab_size": 4,
"translate_tabs_to_spaces": true,
"word_wrap": "auto"
}
尽量做到代码的整齐美观
HTML规范
在页面开头使用DOCTYPE声明启用标准模式
不要忘了设置语言 language 和编码 charset格式
各层元素应该换行,嵌套的元素节点应该缩进,缩进使用4个空格
属性名统一使用小写,使用中划线 - 作为单词的分隔;属性值统一使用双引号,避免使用单引号
不要在自动闭合标签结尾处使用斜线( HTML5规范 指出他们是可选的,如 <img >)
不要忽略可选的闭合标签(如 </li> )
<!DOCTYPE html>
<html lang="zh-CN">
<meta charset="UTF-8">
<title>Page title</title>
<!-- 选择性地使用IE兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
</head>
<img src="images/company_logo.png" alt="Company">
<h1 class="hello-world">Hello, world!</h1>
</body>
</html>
引入CSS和JS时不需要指名 type 属性
因为 text/css 和 text/javascript 已经是它们的默认值 另外,时刻牢记应该在 <head>中引入外部CSS,在<body>末尾引入外部JS
<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css">
<!-- In-document CSS -->
<style>
</style>
<!-- External JS -->
<script src="code_guide.js"></script>
<!-- In-document JS -->
<script>
</script>
boolean值的属性,不需要声明值的属性
在HTML5中,该属性存在即为true,不存在即为false
<!-- 不建议 -->
<input type="text" disabled="disabled">
<!-- 建议 -->
<input type="text" disabled>
<!-- 不建议 -->
<input type="checkbox" value="1" checked="checked">
<input type="checkbox" value="1" checked>
<select>
<option value="1" selected>1</option>
</select>
语义化,避免使用不需要的标签,使用有意义的标签
<!-- Not well -->
<p class="title">我是标题</p>
<span class="avatar">
<img src="...">
</span>
<!-- Better -->
<h3>我是标题</h3>
<img class="avatar" src="...">
不要省略表格table 的 thead tbody
<table>
<thead>
<th>ABC</th>
</thead>
<tbody>
<td>abc</td>
</tbody>
</table>
尽量使用HTML实体符而不是直接使用符号
使用<a>标签作为JS事件处理时,统一使用 href="javascript:;" 伪协议。
因为设置了href之后的<a>标签才具有默认 cursor: pointer 的样式,才能支持Tab切换;
防止点击跳转可以使用 href="#",但页面锚点hash会改变;可以使用 javascript:void(0) 但稍长;可以使用事件处理 return false; event.preventDefault() 但略微麻烦
<!-- Not well -->
<a href="#">more>></a>
<!-- Better -->
<a href="javascript:;">more>></a>
属性应该按照特定的顺序来保证易读性
-
class
-
id
-
name
-
data-*
-
src
,for
,type
,href
,value
,max-length
,max
,min
,pattern
-
placeholder
,title
,alt
-
aria-*
,role
-
required
,readonly
,disabled
class是为高可复用组件设计的,所以应处在第一位;
id更加具体且应该尽量少使用,所以将它放在第二位。
<a class="..." id="..." data-modal="toggle" href="#">Example link</a>
<input class="form-control" type="text">
<img src="..." alt="...">
使用Smarty,Handlebars模板时,注意代码的整洁美观
尽量使用Map映射的结构,而不是条件判断
<!-- Not well -->
<{if $title == 'one'}>
<h2>标题一</h2>
<{elseif $title == 'two'}>
<h2>标题二</h2>
<{elseif $title == 'three'}>
<h2>标题三</h2>
<{/if}>
<!-- Better -->
<{assign var="titleText" value=[
'one' => '标题一',
'two' => '标题二',
'three' => '标题三'
<h2><{$titleText[$title]}></h2>
模板里面符号两端适当地加空格(逗号前不用)
<!-- 逗号后面有空格 -->
<li <{if in_array($beforeAction.currentUrl, $url)}>class="active"<{/if}> 列表 </li>
<!-- 等号两边有空格 -->
<{if $abc == 'cdf'}>
<{/if}>
自定义属性统一使用 data- 前缀
一行标签代码不宜过长,超长时需要适当地按照属性进行分行
但也不是说每个属性都分行
<a class="r-btn r-btn-blue eva-content-btnSave" href="javascript:;"
data-commentID="{{commentID}}"
data-commentType="{{commentType}}"
data-evaID="{{evaID}}"
data-roleStaffID="{{roleStaffID}}"
>确认提交</a>
CSS规范
样式文件头部加上编码规则 统一使用 UTF-8
@charset "UTF-8";
使用四个空格的缩进
每个属性声明末尾都要分号
关于空行
- 文件最后保留一个空行
- '}'后最好跟一个空行,包括scss中嵌套的规则
- 属性之间需要适当的空行
/* not good */
.element {
.dialog {
color: red;
&:after {
/* good */
.element {
.dialog {
color: red;
&:after {
}
关于换行
以下几种情况不需要换行:
- '{' 前
以下几种情况需要换行:
- '{' 后和 '}' 前
- 每个属性独占一行
- 多个规则的分隔符 ',' 后
/* not good */
.element
{color: red; background-color: black;}
/* good */
.element {
color: red;
background-color: black;
/* not good */
.element, .dialog {
/* good */
.element,
.dialog {
}
关于空格
以下几种情况不需要空格:
- 属性名后
- 多个规则的分隔符','前
-
!important
'!' 后 - 属性值中 '(' 后和 ')' 前
- 行末不要有多余的空格
以下几种情况需要空格:
- 属性值前
- 选择器 '>', '+', '~' 前后
- '{' 前
-
!important
'!' 前 -
@else
前后 - 属性值中的 ',' 后
- 注释 '/*' 后和 '*/' 前
/* not good */
.element {
color :red! important;
background-color: rgba(0,0,0,.5);
/* good */
.element {
color: red !important;
background-color: rgba(0, 0, 0, .5);
/* not good */
.element ,
.dialog{
/* good */
.element,
.dialog {
/* not good */
.element>.dialog{
/* good */
.element > .dialog{
/* not good */
.element{
/* good */
.element {
/* not good */
}@else{
/* good */
@if {
} @else {
}
属性选择器的属性值需要引号,url 里的内容需要引号
.element:after {
content: "";
background-image: url("logo.png");
li[data-type="single"] {
}
类名参考 BEM命名规范
ID以及SASS中相关的变量命名使用小驼峰
/* class */
.form-content {
/* id */
#myDialog {
/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
/* 混合 */
@mixin centerBlock {
/* placeholder */
%myDialog {
}
颜色16进制用小写字母,且尽量使用简写形式
/* not good */
.element {
color: #ABCDEF;
background-color: #001122;
/* good */
.element {
color: #abcdef;
background-color: #012;
}
不要为 0 指定单位,去掉小数点前后的 0
/* not good */
.element {
color: rgba(0, 0, 0, 0.5);
/* good */
.element {
color: rgba(0, 0, 0, .5);
/* not good */
.element {
width: 50.0px;
/* good */
.element {
width: 50px;
/* not good */
.element {
width: 0px;
/* good */
.element {
width: 0;
}
避免使用CSS中的@import ,应使用 <link>方式引入CSS文件
<!-- Not well -->
<style>
@import url("more.css");
</style>
<!-- Better -->
<link rel="stylesheet" href="core.css">
@import
引入的文件不需要开头的 '_' 和结尾的'.scss';
/* 引入 _variable.scss */
/* not good */
@import "_variable.scss";
/* good */
@import "variable";
尽量将媒体查询的规则靠近与他们相关的规则
不要将他们一起整个放到一个独立的样式文件中,或者丢在文档的最底部
使用前缀属性时,应通过缩进使取值垂直对齐
且私有属性在前,标准属性在后
.selector {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
}
注意属性简写的使用,避免滥用导致覆盖某些样式
如果使用简写,需保证清楚相应顺序的影响,且不会导致其他问题
- padding
- margin
- background
- border
- border-radius
- transition
- animation
- font
选择器嵌套层数不宜过长
/* not good */
.table > thead > tr > th { … }
.table > thead > tr > td { … }
/* good */
.table > thead > tr {
> th { … }
> td { … }
}
尽量不要在HTML中通过 style=... 内联样式
注意属性的声明顺序
相关的属性声明应当归为一组,参考按照下面的顺序排列, 另参考
- Positioning 定位
- Box model 盒模型
- Typographic 排版
- Visual 外观
- 其他
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Other */
opacity: 1;
}
sublime中可安装使用 CSSComb 插件进行格式转换
1 {
2 // If plugin has trouble finding Node.js, replace this string with path
3 // to your `node` bin
4 "node-path" : ":/usr/local/bin",
5 // Full list of supported options and acceptable values can be found here:
6 // https://github.com/csscomb/csscomb.js/blob/master/doc/options.md
7 "config": {
8 // Whether to add a semicolon after the last value/mixin.
9 "always-semicolon": true,
10 // Set indent for code inside blocks, including media queries and nested rules.
11 "block-indent": " ",
12 // Unify case of hexadecimal colors.
13 "color-case": "lower",
14 // Whether to expand hexadecimal colors or use shorthands.
15 "color-shorthand": true,
16 // Unify case of element selectors.
17 "element-case": "lower",
18 // Add/remove line break at EOF.
19 "eof-newline": true,
20 // Add/remove leading zero in dimensions.
21 "leading-zero": false,
22 // Unify quotes style.
23 "quotes": "double",
24 // Remove all rulesets that contain nothing but spaces.
25 "remove-empty-rulesets": true,
26 // Set space after `:` in declarations.
27 "space-after-colon": " ",
28 // Set space after combinator (for example, in selectors like `p > a`).
29 "space-after-combinator": " ",
30 // Set space after `{`.
31 "space-after-opening-brace": "\n",
32 // Set space after selector delimiter.
33 "space-after-selector-delimiter": "\n",
34 // Set space before `}`.
35 "space-before-closing-brace": "\n",
36 // Set space before `:` in declarations.
37 "space-before-colon": "",
38 // Set space before combinator (for example, in selectors like `p > a`).
39 "space-before-combinator": " ",
40 // Set space before `{`.
41 "space-before-opening-brace": " ",
42 // Set space before selector delimiter.
43 "space-before-selector-delimiter": "",
44 // Set space between declarations (i.e. `color: tomato`).
45 "space-between-declarations": "\n",
46 // Whether to trim trailing spaces.
47 "strip-spaces": true,
48 // Whether to remove units in zero-valued dimensions.
49 "unitless-zero": true,
50 // Whether to align prefixes in properties and values.
51 "vendor-prefix-align": true,
52 // Sort properties in particular order.
53 "sort-order": [
54 "font",
55 "font-family",
56 "font-size",
57 "font-weight",
58 "font-style",
59 "font-variant",
60 "font-size-adjust",
61 "font-stretch",
62 "font-effect",
63 "font-emphasize",
64 "font-emphasize-position",
65 "font-emphasize-style",
66 "font-smooth",
67 "line-height",
68 "position",
69 "z-index",
70 "top",
71 "right",
72 "bottom",
73 "left",
74 "display",
75 "visibility",
76 "float",
77 "clear",
78 "overflow",
79 "overflow-x",
80 "overflow-y",
81 "-ms-overflow-x",
82 "-ms-overflow-y",
83 "clip",
84 "zoom",
85 "flex-direction",
86 "flex-order",
87 "flex-pack",
88 "flex-align",
89 "-webkit-box-sizing",
90 "-moz-box-sizing",
91 "box-sizing",
92 "width",
93 "min-width",
94 "max-width",
95 "height",
96 "min-height",
97 "max-height",
98 "margin",
99 "margin-top",
100 "margin-right",
101 "margin-bottom",
102 "margin-left",
103 "padding",
104 "padding-top",
105 "padding-right",
106 "padding-bottom",
107 "padding-left",
108 "table-layout",
109 "empty-cells",
110 "caption-side",
111 "border-spacing",
112 "border-collapse",
113 "list-style",
114 "list-style-position",
115 "list-style-type",
116 "list-style-image",
117 "content",
118 "quotes",
119 "counter-reset",
120 "counter-increment",
121 "resize",
122 "cursor",
123 "-webkit-user-select",
124 "-moz-user-select",
125 "-ms-user-select",
126 "user-select",
127 "nav-index",
128 "nav-up",
129 "nav-right",
130 "nav-down",
131 "nav-left",
132 "-webkit-transition",
133 "-moz-transition",
134 "-ms-transition",
135 "-o-transition",
136 "transition",
137 "-webkit-transition-delay",
138 "-moz-transition-delay",
139 "-ms-transition-delay",
140 "-o-transition-delay",
141 "transition-delay",
142 "-webkit-transition-timing-function",
143 "-moz-transition-timing-function",
144 "-ms-transition-timing-function",
145 "-o-transition-timing-function",
146 "transition-timing-function",
147 "-webkit-transition-duration",
148 "-moz-transition-duration",
149 "-ms-transition-duration",
150 "-o-transition-duration",
151 "transition-duration",
152 "-webkit-transition-property",
153 "-moz-transition-property",
154 "-ms-transition-property",
155 "-o-transition-property",
156 "transition-property",
157 "-webkit-transform",
158 "-moz-transform",
159 "-ms-transform",
160 "-o-transform",
161 "transform",
162 "-webkit-transform-origin",
163 "-moz-transform-origin",
164 "-ms-transform-origin",
165 "-o-transform-origin",
166 "transform-origin",
167 "-webkit-animation",
168 "-moz-animation",
169 "-ms-animation",
170 "-o-animation",
171 "animation",
172 "-webkit-animation-name",
173 "-moz-animation-name",
174 "-ms-animation-name",
175 "-o-animation-name",
176 "animation-name",
177 "-webkit-animation-duration",
178 "-moz-animation-duration",
179 "-ms-animation-duration",
180 "-o-animation-duration",
181 "animation-duration",
182 "-webkit-animation-play-state",
183 "-moz-animation-play-state",
184 "-ms-animation-play-state",
185 "-o-animation-play-state",
186 "animation-play-state",
187 "-webkit-animation-timing-function",
188 "-moz-animation-timing-function",
189 "-ms-animation-timing-function",
190 "-o-animation-timing-function",
191 "animation-timing-function",
192 "-webkit-animation-delay",
193 "-moz-animation-delay",
194 "-ms-animation-delay",
195 "-o-animation-delay",
196 "animation-delay",
197 "-webkit-animation-iteration-count",
198 "-moz-animation-iteration-count",
199 "-ms-animation-iteration-count",
200 "-o-animation-iteration-count",
201 "animation-iteration-count",
202 "-webkit-animation-direction",
203 "-moz-animation-direction",
204 "-ms-animation-direction",
205 "-o-animation-direction",
206 "animation-direction",
207 "text-align",
208 "-webkit-text-align-last",
209 "-moz-text-align-last",
210 "-ms-text-align-last",
211 "text-align-last",
212 "vertical-align",
213 "white-space",
214 "text-decoration",
215 "text-emphasis",
216 "text-emphasis-color",
217 "text-emphasis-style",
218 "text-emphasis-position",
219 "text-indent",
220 "-ms-text-justify",
221 "text-justify",
222 "letter-spacing",
223 "word-spacing",
224 "-ms-writing-mode",
225 "text-outline",
226 "text-transform",
227 "text-wrap",
228 "text-overflow",
229 "-ms-text-overflow",
230 "text-overflow-ellipsis",
231 "text-overflow-mode",
232 "-ms-word-wrap",
233 "word-wrap",
234 "word-break",
235 "-ms-word-break",
236 "-moz-tab-size",
237 "-o-tab-size",
238 "tab-size",
239 "-webkit-hyphens",
240 "-moz-hyphens",
241 "hyphens",
242 "pointer-events",
243 "opacity",
244 "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
245 "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
246 "-ms-interpolation-mode",
247 "color",
248 "border",
249 "border-width",
250 "border-style",
251 "border-color",
252 "border-top",
253 "border-top-width",
254 "border-top-style",
255 "border-top-color",
256 "border-right",
257 "border-right-width",
258 "border-right-style",
259 "border-right-color",
260 "border-bottom",
261 "border-bottom-width",
262 "border-bottom-style",
263 "border-bottom-color",
264 "border-left",
265 "border-left-width",
266 "border-left-style",
267 "border-left-color",
268 "-webkit-border-radius",
269 "-moz-border-radius",
270 "border-radius",
271 "-webkit-border-top-left-radius",
272 "-moz-border-radius-topleft",
273 "border-top-left-radius",
274 "-webkit-border-top-right-radius",
275 "-moz-border-radius-topright",
276 "border-top-right-radius",
277 "-webkit-border-bottom-right-radius",
278 "-moz-border-radius-bottomright",
279 "border-bottom-right-radius",
280 "-webkit-border-bottom-left-radius",
281 "-moz-border-radius-bottomleft",
282 "border-bottom-left-radius",
283 "-webkit-border-image",
284 "-moz-border-image",
285 "-o-border-image",
286 "border-image",
287 "-webkit-border-image-source",
288 "-moz-border-image-source",
289 "-o-border-image-source",
290 "border-image-source",
291 "-webkit-border-image-slice",
292 "-moz-border-image-slice",
293 "-o-border-image-slice",
294 "border-image-slice",
295 "-webkit-border-image-width",
296 "-moz-border-image-width",
297 "-o-border-image-width",
298 "border-image-width",
299 "-webkit-border-image-outset",
300 "-moz-border-image-outset",
301 "-o-border-image-outset",
302 "border-image-outset",
303 "-webkit-border-image-repeat",
304 "-moz-border-image-repeat",
305 "-o-border-image-repeat",
306 "border-image-repeat",
307 "outline",
308 "outline-width",
309 "outline-style",
310 "outline-color",
311 "outline-offset",
312 "background",
313 "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
314 "background-color",
315 "background-image",
316 "background-repeat",
317 "background-attachment",
318 "background-position",
319 "background-position-x",
320 "-ms-background-position-x",
321 "background-position-y",
322 "-ms-background-position-y",
323 "-webkit-background-clip",
324 "-moz-background-clip",
325 "background-clip",
326 "background-origin",
327 "-webkit-background-size",
328 "-moz-background-size",
329 "-o-background-size",
330 "background-size",
331 "box-decoration-break",
332 "-webkit-box-shadow",
333 "-moz-box-shadow",
334 "box-shadow",
335 "filter:progid:DXImageTransform.Microsoft.gradient",
336 "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
337 "text-shadow"
338 ]
339 }
340 }
JavaScript规范
使用四个空格的缩进
不要省略各个情况的分号
var x = 1;
} while (x < 10);
showTip($tip, function() {
});
字符串统一使用单引号 ‘’
// not good
var x = "test";
// good
var y = 'foo',
z = '<div id="test"></div>';
用'===', '!=='代替'==', '!=';
关于命名
- 使用有意义的命名,默认使用小驼峰式命名(某些参数因数据库设计的原因,也可使用大驼峰,主要参照接口文档)
- 'ID' 在变量名中全大写
- 'URL' 在变量名中全大写
- 'Android' 在变量名中大写第一个字母
- 'iOS' 在变量名中小写第一个,大写后两个字母
- 常量全大写,用下划线连接
- 构造函数,大写第一个字母
- jQuery对象必须以 '$' 开头命名
var thisIsMyName;
var goodID;
var reportURL;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name;
// not good
var body = $('body');
// good
var $body = $('body');
关于空格
以下几种情况不需要空格:
- 对象的属性名后
- 前缀一元运算符后
- 后缀一元运算符前
- 函数调用括号前
- 无论是函数声明还是函数表达式,'(' 前不要空格
- 数组的 '[' 后和 ']' 前
- 对象的 '{' 后和 '}' 前
- 运算符 '(' 后和 ')' 前
以下几种情况需要空格:
- 二元运算符前后
- 三元运算符 '?:' 前后
- 代码块 '{' 前
-
下列关键字前:
else
,while
,catch
,finally
-
下列关键字后:
if
,else
,for
,while
,do
,switch
,case
,try
,catch
,finally
,with
,return
,typeof
- 单行注释 '//' 后(若单行注释和代码同行,则 '//' 前也需要),多行注释 '*' 后
- 对象的属性值前
- for 循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
- 无论是函数声明还是函数表达式,'{' 前一定要有空格
- 函数的参数之间
// not good
var a = {
// good
var a = {
// not good
++ x;
y ++;
z = x?1:2;
// good
z = x ? 1 : 2;
// not good
var a = [ 1, 2 ];
// good
var a = [1, 2];
// not good
var a = ( 1+2 )*3;
// good
var a = (1 + 2) * 3;
// no space before '(', one space before '{', one space between function parameters
var doSomething = function(a, b, c) {
// do something
// no space before '('
doSomething(item);
// not good
for(i=0;i<6;i++){
// good
for (i = 0; i < 6; i++) {
}
关于空行
以下几种情况需要空行:
- 变量声明后(当变量声明在代码块的最后一行时,则无需空行)
- 注释前(当注释在代码块的第一行时,则无需空行)
- 代码块后(在函数调用、数组、对象中则无需空行)
- 文件最后保留一个空行
// need blank line after variable declaration
var x = 1;
// not need blank line when variable declaration is last expression in the current block
if (x >= 1) {
var y = x + 1;
var a = 2;
// need blank line before line comment
function b() {
// not need blank line when comment is first line of block
return a;
// need blank line after blocks
for (var i = 0; i < 2; i++) {
if (true) {
return false;
continue;
var obj = {
foo: function() {
return 1;
bar: function() {
return 2;
// not need blank line when in argument list, array, object
var foo = {
a: 2,
b: function() {
};
关于换行
换行的地方,行末应有 ',' 或其他运算符
换行时需要缩进,但多次换行不需要继续缩进
以下几种情况不需要换行:
-
下列关键字后:
else
,catch
,finally
- 代码块 '{' 前
以下几种情况需要换行:
- 代码块 '{' 后和 '}' 前
- 变量赋值后
// not good
var a = {
, c: 2
x = y
? 1 : 2;
// good
var a = {
b: 1,
x = y ? 1 : 2;
x = y ?
1 : 2;
if (typeof a === "undefined" ||
typeof a.b === "undefined" ||
a.c !== true) {
url = "www.www.www";
} else {
url = "www.www";
// no need line break with 'else', 'catch', 'finally'
if (condition) {
} else {
try {
} catch (e) {
} finally {
// not good
function test()
// good
function test() {
// not good
var a, foo = 7, b,
c, bar = 8;
// good
var a,
foo = 7,
b, c, bar = 8;
代码注释参考注释规范
简化变量的声明,避免多个连续的 var let 声明
// not good
let a = 1;
let b = 2;
let c = 3;
// good
let a = 1,
b = 2,
c = 3;
关于数组和对象的使用
简单的条件语句应该转换为对象映射,使用字面量声明而不是实例化声明
对象属性名默认不加引号,如果必要(属性名带中划线 - )时加引号,需要保持统一
对象以缩进的形式书写,不要写在一行(ES6的解构视情况而定,但一行也不宜过长)
末尾一项不要留逗号
// not good
if (a === 1) {
b = 'a';
} else if (a === 2) {
b = 'aa';
} else if (a === 3) {
b = 'aaa';
} else {
b = 'b';
// good
var obj = {
1: 'a',
2: 'aa',
3: 'aaa'
b = obj[a] || 'b';
// not good
function Book() {
var book = new Book();
book.name = 'book1';
book.ages = new Array(1, 2, 3);
// good
var book = {
name: 'book1',
ages: [1, 2, 3]
// not good
var a = {
'b': 1
var a = {
b: 1,
'c-d': 2
var a = {b: 1};
var a = {
b: 1,
c: 2,
// good
var a = {
'b': 1,
'c-d': 2
var a = {
b: 1,
};
if while try 等携带的括号不可省略
包括 if
,
else
,
for
,
while
,
do
,
switch
,
try
,
catch
,
finally
,
with 等,应该统一使用括号包裹成块,即使只有一行
// not good
if (condition)
doSomething();
// good
if (condition) {
doSomething();
}
不要直接使用 undefined 进行变量的判断
// not good
if (person === undefined) {
// good
if (typeof person === 'undefined') {
}
使用类型转换,短路断路运算 || && ,三目运算符
这里不包括使用 == 的类型转换
短路断路和三目仅在简单的逻辑里使用,避免嵌套负杂的多层,且应添加适当的注释说明
// not good
if ($elem.length === 0) {
showTip();
// good
if (!$elem.length) {
showTip();
// better
!$elem.length && showTip();
// not good
if (a) {
b = a;
c = 10;
} else {
b = 100;
c = 100;
// good
b = a || 100;
c = a ? 10 : 100;
for-in 里一定要有hasOwnProperty的判断
for (key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key]);
}
上下文 this 的别名,仅仅使用 that _this self
避免使用 me
switch 中 应该设置 default
如果不设置,需要写明注释
// good
switch (condition) {
case 1:
case 2:
break;
case 3:
// why fall through
case 4
break;
// why no default
}
jQuery的链式调用分层应换行缩进
// not good
$elem.addClass('abc').hide().find('h1').text('abc');
// good
$elem.addClass('abc').hide()
.find('h1').text('abc');
尽量使用函数声明,而不是函数表达式
// not good
var foo = function () {
// do something
// good
function foo () {
// do something
}
关于字符串,HTML元素的拼接
注意换行和缩进,拼接HTML的时候注意性能,ES6环境中应该使用模板字符串
// not good
var str = '<div><p>abc<p><p>aaa<span>sss</span></p></div>';
// good
var str = '' +
'<div>' +
'<p>abc<p>' +
'<p>aaa' +
'<span>sss</span>' +
'</p>' +
'</div>';
// ES6中
// not good
for (var i = 0; i < 10; ++i) {
$('select').append('<option value="' + i + '">选项' + (i + 1)+ '</option>' );
// good
var $select = $('select');
option = [];
for (var i = 0; i < 10; ++i) {
option.push(`<option value="${i}">选项${i + 1}</option>`);
$select.html(option.join(''));
尽量不设置全局变量
如果设置全局变量,变量名应带有”全局“相关的字样
var globalMsg = '';
var globalVariable = {
msg: 'aa',
number: 12
};
二、CSS命名规范
三、注释规范
好的注释不仅能够表达”是什么“,还能表达”为什么“
HTML注释规范
注释以字符 <!-- 开始,以字符 --> 结束
注释独占一行,置于代码上方,左右闭合前保留一个空格
对于模块(或者某个代码块)注释,需要增加 首(S)尾(E) 标识,模块之间相隔一行
<!-- Comment Text -->
<div>...</div>
<!-- S Comment Text 1 -->
<div class="mod_a">
<!-- E Comment Text 1 -->
<!-- S Comment Text 2 -->
<div class="mod_b">
<!-- E Comment Text 2 -->
Smarty 前端模板注释规范
注释以字符 <{* 开始,以字符 *}> 结束
当只是作为代码意义标识的时候,统一使用HTML的注释规则 <!-- comment -->
当需要注释不执行某个Smarty部分时,需要遵循Smarty的注释规则(建议首尾独占一行,注释的文字在首行之后,与 <{* 间隔一个空格,如下)
<!-- S 头部模块 -->
<link .....>
<{include file='./header.tpl'}>
<!-- E 头部模块 -->
<{* 暂不引人
<h1><{block name="page_header"}><{/block}></h1>
*}>
CSS/SASS 注释规范
注释以字符 /* 开始,以字符 */ 结束,左右闭合前保留一个空格,建议一行注释
也可在一行代码后面,注意与代码间有空格
/* 某个表单 */
.search-form {
&__left {
position: absolute; /* 定位 */
}
JS 注释规范
单行注释
使用双斜线 // ,双斜线后带一个空格,双斜线与下一行缩进一致
可位于代码行的末尾,需与代码间隔一个空格
if (condition) {
// if you made it here, then all security checks passed
allowed();
var zhangsan = 'zhangsan'; // one space after code
多行注释
注释以字符 /* 开始,以字符 */ 结束,至少三行,参考以下例子
建议在难以理解的代码块,逻辑性强,特殊处理的地方使用
/*
* one space after '*'
var x = 1;
文档注释
JSDoc规范 JSDoc用于根据规范的JS注释自动生成对应的API文档,如果不需要生成文档,只需遵循以下常用规范
注释前要空一行,建议在所有函数,类,常量中使用
常用的几个标签:@author @license @copyright @param @return @example @version @class @constructor @type @constant @todo , 更多标签参考
@param中的 {[type]} 使用小写开头,多个type使用 | 分隔,且尽量保持各项的对齐
常用的type类型有 boolean(布尔值), number(数字),string(字符串),array(数组), object(对象), function(函数),jqueryObject(jQuery对象),htmlObject(HTML元素对象)等,也可自定义
/**
* 最大次数
* @constant {number}
const MAX_TIMES = 10;
* 一个自定义类
* @version 1.0.0
* @class MyClass
* @constructor
function MyClass() {
// 名字
this.name = 'defaultName';
MyClass.prototype = {
constructor: MyClass,
* 获取名字
* @return {string} 名字
getName: function() {
return this.name || '';
* 设置名字
* @param {string|array} name 名字,多个名字将以空格分隔
* @example
* setName('ppk')
* setName(['a', 'b'])
setName: (name) => {
this.name = typeof name === 'string' ? name : name.join(' ');
* 异步获取
* @param {string} url 连接
* @param {object} data 数据
* @param {function} cb 成功的回调
* @param {function} errorCb 失败的回调
* @param {function} exceptionCb 异常的回调
* @param {boolean} noLayerLoading 是否显示加载图标
function ajax(url, data, cb, errorCb, exceptionCb, noLayerLoading) {
}
JSX 模板注释规范
JSX其实只是JS的语法糖,所以注释类似JS
一般的注释为以字符 {/* 开始,以字符 */} 结束
let Content = (