Web前端開發基礎規範


 

項目及文件命名規則

項目命名

所有采用小寫方式, 如下劃線分隔。 例:my_project_namejavascript

目錄命名

參照項目命名規則; 有複數結構時,要採用複數命名法。 例:scriptsstylesimagesdata_modelscss

JS文件命名

參照項目命名規則。 例:account_model.jshtml

CSS,SCSS文件命名

參照項目命名規則。 例:retina_sprites.scssjava

HTML文件命名

參照項目命名規則。 例:error_report.htmljquery

HTML

語法

縮進使用soft tab(4個空格); 嵌套的節點應該縮進; 在屬性上,使用雙引號,不要使用單引號; 屬性名全小寫,用中劃線作分隔符; 不要在自動閉合標籤結尾處使用斜線(HTML5 規範 指出他們是可選的); 不要忽略可選的關閉標籤,例:  和</body>。 代碼示例:git

```htmlgithub

<!DOCTYPE html>
<html>
<head>
<title>Page title</title>
</head>
<body>
<img src="images/company_logo.png" alt="Company">

<h1 class="hello-world">Hello, world!</h1>
</body>
</html>

```web

HTML5 doctype

在頁面開頭使用這個簡單地doctype來啓用標準模式,使其在每一個瀏覽器中儘量一致的展示; 雖然doctype不區分大小寫,可是按照慣例,doctype大寫。 不一樣doctype在不一樣瀏覽器下會觸發不一樣的渲染模式,訪問下面連接瞭解更多 https://hsivonen.fi/doctype/http://www.w3school.com.cn/tags/tag_doctype.aspexpress

代碼示例:數組

```html

<!DOCTYPE html>
<html>
    ...
</html>

```

lang屬性

根據HTML5規範: 應在html標籤上加上lang屬性。這會給語音工具和翻譯工具幫助,告訴它們應當怎麼去發音和翻譯。 更多關於 lang 屬性的說明在這裏http://w3c.github.io/html/semantics.html#the-html-element 具體的語言列表請查看這裏https://msdn.microsoft.com/en-us/library/ms533052(v=vs.85).aspx

代碼示例:

```html

<!DOCTYPE html>
<html lang="en-us">
    ...
</html>

```

字符編碼

經過聲明一個明確的字符編碼,讓瀏覽器輕鬆、快速的肯定適合網頁內容的渲染方式,一般指定爲'UTF-8'。 代碼示例:

```html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
    ...
</html>

```

IE兼容模式

用 <meta>標籤能夠指定頁面應該用什麼版本的IE來渲染; 若是你想要了解更多,請點擊這裏http://www.tuicool.com/articles/ra6Fjuj

代碼示例:

```html

<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="X-UA-Compatible"content="IE=Edge">
</head>
    ...
</html>

```

引入CSS, JS

根據HTML5規範, 一般在引入CSSJS時不須要指明 type,由於 text/css和 text/javascript 分別是他們的默認值。 HTML5 規範連接 使用link: http://www.w3school.com.cn/tags/tag_link.asp 使用style:http://www.w3school.com.cn/tags/tag_style.asp 使用script:http://www.w3school.com.cn/tags/tag_script.asp

代碼示例:

```html

<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css">

<!-- In-document CSS -->
<style>
...
</style>

<!-- External JS -->
<script src="code_guide.js"></script>
shux
<!-- In-document JS -->
<script>
...
</script>

```

屬性順序

屬性應該按照特定的順序出現以保證易讀性;

class
id
name
data-*
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-*, role
required, readonly, disabled

class是爲高可複用組件設計的,因此應處在第一位; id更加具體且應該儘可能少使用,因此將它放在第二位。 代碼示例:

```html

<a class="..." id="..." data-modal="toggle" href="#">Example link</a>

<input class="form-control" type="text">

<img src="..."alt="...">

```

boolean屬性

boolean屬性指不須要聲明取值的屬性,XHTML須要每一個屬性聲明取值,可是HTML5並不須要; 更多內容能夠參考 https://whatwg-cn.github.io/html/# boolean-attributes:boolean屬性的存在表示取值爲true,不存在則表示取值爲false

代碼示例:

```html

<input type="text"disabled>

<input type="checkbox" value="1" checked>

<select>
<option value="1" selected>1</option>
</select>

```

JS生成標籤

在JS文件中生成標籤讓內容變得更難查找,更難編輯,性能更差。應該儘可能避免這種狀況的出現。

減小標籤數量

在編寫HTML代碼時,須要儘可能避免多餘的父節點; 不少時候,須要經過迭代和重構來使HTML變得更少。 代碼示例:

```html

<!-- Not well -->
<span class="avatar">
<img src="...">
</span>

<!-- Better -->
<img class="avatar" src="...">

```

實用高於完美

儘可能遵循HTML標準和語義,可是不該該以浪費實用性做爲代價; 任什麼時候候都要用盡可能小的複雜度和儘可能少的標籤來解決問題。

CSS,SCSS

縮進

使用soft tab(4個空格)。 代碼示例:

```css

.element{
    position:absolute;
    top:10px;
    left:10px;
    border-radius:10px;
    width:50px;
    height:50px;
}

```

分號

每一個屬性聲明末尾都要加分號。 代碼示例:

```css

.element{
    width:20px;
    height:20px;
    background-color:red;
}

```

空格

如下幾種狀況不須要空格:

  • 屬性名後
  • 多個規則的分隔符','前
  • !important '!'後
  • 行末不要有多餘的空格

如下幾種狀況須要空格:

  • 屬性值前
  • 選擇器'>', '+', '~'先後
  • '{'前
  • !important '!'前
  • @else 先後
  • 屬性值中的','後
  • 註釋'/'後和'/'前

代碼示例:

```css

/* 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 */
@if{
...
}@else{
...
}

/* good */
@if {
...
} @else {
...
}

```

空行

如下幾種狀況須要空行:

  • 文件最後保留一個空行
  • '}'後最好跟一個空行,包括scss中嵌套的規則
  • 屬性之間須要適當的空行,具體見屬性聲明順序

代碼示例:

```css

/* not good */
.element {
    ...
}
.dialog {
    color:red;
&:after{
...
    }
}

/* good */
.element {
    ...
}

.dialog {
    color:red;

&:after{
...
    }
}

```

換行

如下幾種狀況不須要換行:

  • '{'前

如下幾種狀況須要換行:

  • '{'後和'}'前
  • 每一個屬性獨佔一行
  • 多個規則的分隔符','後

代碼示例:

```css

/* not good */
.element
{
    color:red; 
    background-color:black;
}

/* good */
.element {
    color:red;
    background-color:black;
}

/* not good */
.element,.dialog {
...
}

/* good */
.element,
.dialog {
...
}

```

註釋

  • 註釋統一用'/* */'(scss中也不要用'//'),具體參照示例中的寫法;
  • 縮進與下一行代碼保持一致;
  • 可位於一個代碼行的末尾,與代碼間隔一個空格。 代碼示例:

```css

/* Modal header */
.modal-header {
...
}

/*
 * Modal header
 */
.modal-header {
...
}

.modal-header {
    /* 50px */
    width:50px;

    color:red; /* color red */
}

```

引號

  • 最外層統一使用雙引號;
  • url的內容要用引號;
  • 屬性選擇器中的屬性值須要引號。 代碼示例:

```css

element:after {
    content:"";
    background-image:url("logo.png");
}

li[data-type="single"] {
...
}

```

命名

  • 類名使用小寫字母,以中劃線分隔
  • id採用駝峯式命名
  • scss中的變量、函數、混合、placeholder採用駝峯式命名

更多關於css命名的技巧,請訪問http://www.zhangxinxu.com/wordpress/2010/09/%E7%B2%BE%E7%AE%80%E9%AB%98%E6%95%88%E7%9A%84css%E5%91%BD%E5%90%8D%E5%87%86%E5%88%99%E6%96%B9%E6%B3%95/

代碼示例:

```css

/* class */
.element-content {
...
}

/* id */
#myDialog {
...
}

/* 變量 */
$colorBlack:#000;

/* 函數 */
@functionpxToRem($px) {
...
}

/* 混合 */
@mixincenterBlock {
...
}

/* placeholder */
%myDialog {
...
}

```

屬性聲明順序

相關的屬性聲明按右邊的順序作分組處理,組之間須要有一個空行。 代碼示例:

```css

.declaration-order {
    display:block;
    float:right;
    position:absolute;
    top:0;
    right:0;
    bottom:0;
    left:0;
    z-index:100;

    border:1pxsolid#e5e5e5;
    border-radius:3px;
    width:100px;
    height:100px;

    font:normal13px"Helvetica Neue",sans-serif;
    line-height:1.5;
    text-align:center;

    color:#333;
    background-color:#f5f5f5;

    opacity:1;
}
// 下面是推薦的屬性的順序
[
    [
        "display",
        "visibility",
        "float",
        "clear",
        "overflow",
        "overflow-x",
        "overflow-y",
        "clip",
        "zoom"
    ],
    [
        "table-layout",
        "empty-cells",
        "caption-side",
        "border-spacing",
        "border-collapse",
        "list-style",
        "list-style-position",
        "list-style-type",
        "list-style-image"
    ],
    [
        "-webkit-box-orient",
        "-webkit-box-direction",
        "-webkit-box-decoration-break",
        "-webkit-box-pack",
        "-webkit-box-align",
        "-webkit-box-flex"
    ],
    [
        "position",
        "top",
        "right",
        "bottom",
        "left",
        "z-index"
    ],
    [
        "margin",
        "margin-top",
        "margin-right",
        "margin-bottom",
        "margin-left",
        "-webkit-box-sizing",
        "-moz-box-sizing",
        "box-sizing",
        "border",
        "border-width",
        "border-style",
        "border-color",
        "border-top",
        "border-top-width",
        "border-top-style",
        "border-top-color",
        "border-right",
        "border-right-width",
        "border-right-style",
        "border-right-color",
        "border-bottom",
        "border-bottom-width",
        "border-bottom-style",
        "border-bottom-color",
        "border-left",
        "border-left-width",
        "border-left-style",
        "border-left-color",
        "-webkit-border-radius",
        "-moz-border-radius",
        "border-radius",
        "-webkit-border-top-left-radius",
        "-moz-border-radius-topleft",
        "border-top-left-radius",
        "-webkit-border-top-right-radius",
        "-moz-border-radius-topright",
        "border-top-right-radius",
        "-webkit-border-bottom-right-radius",
        "-moz-border-radius-bottomright",
        "border-bottom-right-radius",
        "-webkit-border-bottom-left-radius",
        "-moz-border-radius-bottomleft",
        "border-bottom-left-radius",
        "-webkit-border-image",
        "-moz-border-image",
        "-o-border-image",
        "border-image",
        "-webkit-border-image-source",
        "-moz-border-image-source",
        "-o-border-image-source",
        "border-image-source",
        "-webkit-border-image-slice",
        "-moz-border-image-slice",
        "-o-border-image-slice",
        "border-image-slice",
        "-webkit-border-image-width",
        "-moz-border-image-width",
        "-o-border-image-width",
        "border-image-width",
        "-webkit-border-image-outset",
        "-moz-border-image-outset",
        "-o-border-image-outset",
        "border-image-outset",
        "-webkit-border-image-repeat",
        "-moz-border-image-repeat",
        "-o-border-image-repeat",
        "border-image-repeat",
        "padding",
        "padding-top",
        "padding-right",
        "padding-bottom",
        "padding-left",
        "width",
        "min-width",
        "max-width",
        "height",
        "min-height",
        "max-height"
    ],
    [
        "font",
        "font-family",
        "font-size",
        "font-weight",
        "font-style",
        "font-variant",
        "font-size-adjust",
        "font-stretch",
        "font-effect",
        "font-emphasize",
        "font-emphasize-position",
        "font-emphasize-style",
        "font-smooth",
        "line-height",
        "text-align",
        "-webkit-text-align-last",
        "-moz-text-align-last",
        "-ms-text-align-last",
        "text-align-last",
        "vertical-align",
        "white-space",
        "text-decoration",
        "text-emphasis",
        "text-emphasis-color",
        "text-emphasis-style",
        "text-emphasis-position",
        "text-indent",
        "-ms-text-justify",
        "text-justify",
        "letter-spacing",
        "word-spacing",
        "-ms-writing-mode",
        "text-outline",
        "text-transform",
        "text-wrap",
        "-ms-text-overflow",
        "text-overflow",
        "text-overflow-ellipsis",
        "text-overflow-mode",
        "-ms-word-wrap",
        "word-wrap",
        "-ms-word-break",
        "word-break"
    ],
    [
        "color",
        "background",
        "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
        "background-color",
        "background-image",
        "background-repeat",
        "background-attachment",
        "background-position",
        "-ms-background-position-x",
        "background-position-x",
        "-ms-background-position-y",
        "background-position-y",
        "-webkit-background-clip",
        "-moz-background-clip",
        "background-clip",
        "background-origin",
        "-webkit-background-size",
        "-moz-background-size",
        "-o-background-size",
        "background-size"
    ],
    [
        "outline",
        "outline-width",
        "outline-style",
        "outline-color",
        "outline-offset",
        "opacity",
        "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
        "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
        "-ms-interpolation-mode",
        "-webkit-box-shadow",
        "-moz-box-shadow",
        "box-shadow",
        "filter:progid:DXImageTransform.Microsoft.gradient",
        "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
        "text-shadow"
    ],
    [
        "-webkit-transition",
        "-moz-transition",
        "-ms-transition",
        "-o-transition",
        "transition",
        "-webkit-transition-delay",
        "-moz-transition-delay",
        "-ms-transition-delay",
        "-o-transition-delay",
        "transition-delay",
        "-webkit-transition-timing-function",
        "-moz-transition-timing-function",
        "-ms-transition-timing-function",
        "-o-transition-timing-function",
        "transition-timing-function",
        "-webkit-transition-duration",
        "-moz-transition-duration",
        "-ms-transition-duration",
        "-o-transition-duration",
        "transition-duration",
        "-webkit-transition-property",
        "-moz-transition-property",
        "-ms-transition-property",
        "-o-transition-property",
        "transition-property",
        "-webkit-transform",
        "-moz-transform",
        "-ms-transform",
        "-o-transform",
        "transform",
        "-webkit-transform-origin",
        "-moz-transform-origin",
        "-ms-transform-origin",
        "-o-transform-origin",
        "transform-origin",
        "-webkit-animation",
        "-moz-animation",
        "-ms-animation",
        "-o-animation",
        "animation",
        "-webkit-animation-name",
        "-moz-animation-name",
        "-ms-animation-name",
        "-o-animation-name",
        "animation-name",
        "-webkit-animation-duration",
        "-moz-animation-duration",
        "-ms-animation-duration",
        "-o-animation-duration",
        "animation-duration",
        "-webkit-animation-play-state",
        "-moz-animation-play-state",
        "-ms-animation-play-state",
        "-o-animation-play-state",
        "animation-play-state",
        "-webkit-animation-timing-function",
        "-moz-animation-timing-function",
        "-ms-animation-timing-function",
        "-o-animation-timing-function",
        "animation-timing-function",
        "-webkit-animation-delay",
        "-moz-animation-delay",
        "-ms-animation-delay",
        "-o-animation-delay",
        "animation-delay",
        "-webkit-animation-iteration-count",
        "-moz-animation-iteration-count",
        "-ms-animation-iteration-count",
        "-o-animation-iteration-count",
        "animation-iteration-count",
        "-webkit-animation-direction",
        "-moz-animation-direction",
        "-ms-animation-direction",
        "-o-animation-direction",
        "animation-direction"
    ],
    [
        "content",
        "quotes",
        "counter-reset",
        "counter-increment",
        "resize",
        "cursor",
        "-webkit-user-select",
        "-moz-user-select",
        "-ms-user-select",
        "user-select",
        "nav-index",
        "nav-up",
        "nav-right",
        "nav-down",
        "nav-left",
        "-moz-tab-size",
        "-o-tab-size",
        "tab-size",
        "-webkit-hyphens",
        "-moz-hyphens",
        "hyphens",
        "pointer-events"
    ]
]

```

顏色

顏色16進制用小寫字母; 顏色16進制儘可能用簡寫。 代碼示例:

```css

/* not good */
.element {
    color:#ABCDEF;
    background-color:#001122;
}

/* good */
.element {
    color:#abcdef;
    background-color:#012;
}

```

屬性簡寫

屬性簡寫須要你很是清楚屬性值的正確順序,並且在大多數狀況下並不須要設置屬性簡寫中包含的全部值,因此建議儘可能分開聲明會更加清晰;margin 和 padding 相反,須要使用簡寫; 常見的屬性簡寫包括:

font、background、transition、animation

代碼示例:

```css

/* not good */
.element {
    transition: opacity 1s linear 2s;
}

/* good */
.element {
    transition-delay: 2s;
    transition-timing-function: linear;
    transition-duration: 1s;
    transition-property: opacity;
}

```

媒體查詢

儘可能將媒體查詢的規則靠近與他們相關的規則,不要將他們一塊兒放到一個獨立的樣式文件中,或者丟在文檔的最底部,這樣作只會讓你們之後更容易忘記他們。 代碼示例:

```css

.element {
...
}

.element-avatar{
...
}

@media(min-width:480px) {
    .element {
    ...
    }

    .element-avatar {
    ...
    }
}

```

SCSS相關

  • 提交的代碼中不要有 @debug
  • 聲明順序:
    • @extend
    • 不包含 @content 的 @include
    • 包含 @content 的 @include
    • 自身屬性
    • 嵌套規則
  • import 引入的文件不須要開頭的'_'和結尾的'.scss';
  • 嵌套最多不能超過5層;
  • @extend中使用placeholder選擇器;
  • 去掉沒必要要的父級引用符號'&'。

代碼示例:

```css

/* not good */
@import"_dialog.scss";

/* good */
@import"dialog";

/* not good */
.fatal {
@extend .error;
}

/* good */
.fatal {
@extend %error;
}

/* not good */
.element {
&>.dialog {
...
    }
}

/* good */
.element {
>.dialog {
...
    }
}

```

雜項

不容許有空的規則:

  • 元素選擇器用小寫字母;
  • 去掉小數點前面的0;
  • 去掉數字中沒必要要的小數點和末尾的0;
  • 屬性值'0'後面不要加單位;
  • 同個屬性不一樣前綴的寫法須要在垂直方向保持對齊,具體參照下邊的寫法;
  • 無前綴的標準屬性應該寫在有前綴的屬性後面;
  • 不要在同個規則裏出現重複的屬性,若是重複的屬性是連續的則不要緊;
  • 不要在一個文件裏出現兩個相同的規則;
  • 用 border: 0; 代替 border: none;;
  • 選擇器不要超過4層(在scss中若是超過4層應該考慮用嵌套的方式來寫);
  • 發佈的代碼中不要有 @import
  • 儘可能少用'*'選擇器。

代碼示例:

```css

/* not good */
.element {
}

/* not good */
LI {
...
}

/* good */
li {
...
}

/* 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;
}

/* not good */
.element {
    border-radius:3px;
    -webkit-border-radius:3px;
    -moz-border-radius:3px;

    background: linear-gradient(to bottom,#fff0,#eee100%);
    background:-webkit-linear-gradient(top,#fff0,#eee100%);
    background:-moz-linear-gradient(top,#fff0,#eee100%);
}

/* good */
.element {
    -webkit-border-radius:3px;
    -moz-border-radius:3px;
    border-radius:3px;
    background:-webkit-linear-gradient(top,#fff0,#eee100%);
    background:-moz-linear-gradient(top,#fff0,#eee100%);
    background:linear-gradient(to bottom,#fff0,#eee100%);
}

/* not good */
.element {
    color:rgb(0,0,0);
    width:50px;
    color:rgba(0,0,0,.5);
}

/* good */
.element {
    color:rgb(0,0,0);
    color:rgba(0,0,0,.5);
}

```

JavaScript

縮進

使用soft tab(4個空格)。 代碼示例:

```js

var x =1,
    y =1;

if (x < y) {
    x +=10;
} else {
    x +=1;
}

```

單行長度

不要超過80,但若是編輯器開啓word wrap能夠不考慮單行長度。

單個函數代碼行數

單個函數儘可能不要超過40行代碼,無可奈何的狀況下也不要超過100行。代碼行數越多,產生BUG的機率越大,因此儘可能減小單個函數的代碼行數是頗有必要的。減小單個函數的代碼行數,對代碼維護也是很是有益的。

分號

如下幾種狀況後需加分號:

  • 變量聲明
  • 表達式
  • return
  • throw
  • break
  • continue

代碼示例:

```js

/* var declaration */
var x =1;

/* expression statement */
x++;

/* do-while */
do {
    x++;
} while (x <10);

```

空格

如下幾種狀況不須要空格:

  • 對象的屬性名後
  • 前綴一元運算符後
  • 後綴一元運算符前
  • 函數調用括號前
  • 不管是函數聲明仍是函數表達式,'('前不要空格
  • 數組的'['後和']'前
  • 對象的'{'後和'}'前
  • 運算符'('後和')'前

如下幾種狀況須要空格:

  • 二元運算符先後
  • 三元運算符'?:'先後
  • 代碼塊'{'前
  • 下列關鍵字前:elsewhilecatchfinally
  • 下列關鍵字後:ifelseforwhiledoswitchcasetrycatchfinallywithreturntypeof
  • 單行註釋'//'後(若單行註釋和代碼同行,則'//'前也須要),多行註釋'*'後
  • 對象的屬性值前
  • for循環,分號後留有一個空格,前置條件若是有多個,逗號後留一個空格
  • 不管是函數聲明仍是函數表達式,'{'前必定要有空格
  • 函數的參數之間

代碼示例:

```js

// not good
var a = {
    b :1
};

// good
var a = {
    b: 1
};

// not good
++ x;
Y ++;
z = x?1:2;

// good
++x;
y++;
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++){
    x++;
}

// good
for (i = 0; i <6; i++) {
    x++;
}

```

空行

如下幾種狀況須要空行:

  • 變量聲明後(當變量聲明在代碼塊的最後一行時,則無需空行)
  • 註釋前(當註釋在代碼塊的第一行時,則無需空行)
  • 代碼塊後(在函數調用、數組、對象中則無需空行)
  • 文件最後保留一個空行

代碼示例:

```js

// 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
a++;

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() {
        return1;
    },
    bar:function() {
        return2;
    }
};

// not need blank line when in argument list, array, object
func(
    2,
    function() {
        a++;
    },
    3
);

var foo = [
    2,
    function() {
        a++;
        },
    3
];


var foo = {
    a:2,
    b:function() {
        a++;
    },
    c:3
};

```

換行

換行的地方,行末必須有','或者運算符; 如下幾種狀況不須要換行:

  • 下列關鍵字後:else,catchfinally
  • 代碼塊'{'前

如下幾種狀況須要換行:

  • 代碼塊'{'後和'}'前
  • 變量賦值後

代碼示例:

```js

// not good
var a = {
    b:1
    , c:2
};

x = y
?1:2;

// good
var a = {
    b: 1,
    c: 2 
};

x = y ? 1 : 2;
x =y ?
1:2;

// 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;

```

單行註釋

  • 雙斜線後,必須跟一個空格;
  • 縮進與下一行代碼保持一致;
  • 可位於一個代碼行的末尾,與代碼間隔一個空格。

代碼示例:

```js

if (condition) {
    // if you made it here, then all security checks passed
    allowed();
}

var zhangsan = 'zhangsan'; // one space after code

```

多行註釋

最少三行, '*'後跟一個空格,具體參照右邊的寫法; 建議在如下狀況下使用:

  • 難於理解的代碼段
  • 可能存在錯誤的代碼段
  • 瀏覽器特殊的HACK代碼
  • 業務邏輯強相關的代碼

代碼示例:

```js

/*
 * one space after '*'
 */
var x =1;

```

文檔註釋

各種標籤@param@method等請參考http://yuri4ever.github.io/jsdoc/

建議在如下狀況下使用:

  • 全部常量
  • 全部函數
  • 全部類

代碼示例:

```js

/**
 * @func
 * @desc一個帶參數的函數
 * @param {string} a - 參數a
 * @param {number} b=1 - 參數b默認值爲1
 * @param {string} c=1 - 參數c有兩種支持的取值</br>1—表示x</br>2—表示xx
 * @param {object} d - 參數d爲一個對象
 * @param {string} d.e - 參數d的e屬性
 * @param {string} d.f - 參數d的f屬性
 * @param {object[]} g - 參數g爲一個對象數組
 * @param {string} g.h - 參數g數組中一項的h屬性
 * @param {string} g.i - 參數g數組中一項的i屬性
 * @param {string} [j] - 參數j是一個可選參數
 */
function foo(a, b, c, d, g, j) {
    ...
}

```

引號

最外層統一使用單引號。 代碼示例:

```js

// not good
var x ="test";

// good
var y ='foo',
    z ='<div id="test"></div>';

```

變量命名

  • 標準變量採用駝峯式命名(除了對象的屬性外,主要是考慮到cgi返回的數據)
  • 'ID'在變量名中全大寫
  • 'URL'在變量名中全大寫
  • 'Android'在變量名中大寫第一個字母
  • 'iOS'在變量名中小寫第一個,大寫後兩個字母
  • 常量全大寫,用下劃線鏈接
  • 構造函數,大寫第一個字母
  • jquery對象必須以'$'開頭命名

代碼示例:

```js

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');

```

變量聲明

  • 一個函數做用域中全部的變量聲明儘可能提到函數首部。
  • 採用單var聲明多個變量,而且5個變量爲一組,超過5個另起一組。

代碼示例:

```js

function doSomethingWithItems(items) {
    // use one var
    var value =10,
        result= value +10,
        i,
        len,
        count;

    // new
    var total;

    for (i = 0, len = items.length; i < len; i++) {
        result += 10;
    }
}

```

函數

  • 不管是函數聲明仍是函數表達式,'('前不要空格,但'{'前必定要有空格;
  • 函數調用括號前不須要空格;
  • 當即執行函數外必須包一層括號;
  • 不要給inline function命名;
  • 參數之間用', '分隔,注意逗號後有一個空格。

代碼示例:

```js

// no space before '(', but one space before'{'
var doSomething = function(item) {
    // do something
};

function doSomething(item) {
    // do something
}

// not good
doSomething (item);

// good
doSomething(item);

// requires parentheses around immediately invoked function expressions
(function() {
    return1;
})();

// not good
[1, 2].forEach(function x() {
    ...
});

// good
[1, 2].forEach(function() {
    ...
});

// not good
var a = [1, 2, function a() {
    ...
}];

// good
var a = [1, 2, function() {
    ...
}];

// use ', ' between function parameters
var doSomething = function(a, b, c) {
    // do something
};

```

數組、對象

  • 對象屬性名不須要加引號;
  • 對象以縮進的形式書寫,不要寫在一行;
  • 數組、對象最後不要有逗號。

代碼示例:

```js

// not good
var a = {
    'b':1
};

var a = {b:1};

var a = {
    b:1,
    c:2,
};

// good
var a = {
    b:1,
    c:2
};

```

括號

下列關鍵字後必須有大括號(即便代碼塊的內容只有一行):

if, else, for, while, do, switch, try, catch, finally, with。

代碼示例:

```js

// not good
if (condition)
    doSomething();

// good
if (condition) {
    doSomething();
}

```

null

適用場景:

  • 初始化一個未來可能被賦值爲對象的變量
  • 與已經初始化的變量作比較
  • 做爲一個參數爲對象的函數的調用傳參
  • 做爲一個返回對象的函數的返回值

不適用場景:

  • 不要用null來判斷函數調用時有無傳參
  • 不要與未初始化的變量作比較

代碼示例:

```js

// not good
function test(a, b) {
    if (b === null) {
        // not mean b is not supply
        ...
    }
}

var a;

if (a === null) {
    ...
}

// good
var a = null;

if (a === null) {
    ...
}

```

undefined

  • 永遠不要直接使用undefined進行變量判斷;
  • 使用typeof和字符串'undefined'對變量進行判斷。

代碼示例:

```js

// not good
if (person === undefined) {
    ...
}

// good
if (typeof person === 'undefined') {
    ...
}

```

jshint

  • 用'===', '!=='代替'==', '!=';
  • for-in裏必定要有hasOwnProperty的判斷;
  • 不要在內置對象的原型上添加方法,如ArrayDate
  • 不要在內層做用域的代碼裏聲明瞭變量,以後卻訪問到了外層做用域的同名變量;
  • 變量不要先使用後聲明;
  • 不要在一句代碼中單單使用構造函數,記得將其賦值給某個變量;
  • 不要在同個做用域下聲明同名變量;
  • 不要在一些不須要的地方加括號,例:delete(a.b)
  • 不要使用未聲明的變量(全局變量須要加到.jshintrc文件的globals屬性裏面);
  • 不要聲明瞭變量卻不使用;
  • 不要在應該作比較的地方作賦值;
  • debugger不要出如今提交的代碼裏;
  • 數組中不要存在空元素;
  • 不要在循環內部聲明函數;
  • 不要像這樣使用構造函數,例:new function () { ... }, new Object

代碼示例:

```js

// not good
if (a == 1) {
    a++;
}

// good
if (a === 1) {
    a++;
}

// good
for (key in obj) {
    if (obj.hasOwnProperty(key)) {
        // be sure that obj[key] belongs to the object and was not inherited
        console.log(obj[key]);
    }
}

// not good
Array.prototype.count=function(value) {
    Return 4;
};

// not good
var x = 1;

function test() {
    if (true) {
        var x = 0;
    }

    x += 1;
}

// not good
function test() {
    console.log(x);

    var x =1;
}

// not good
new Person();

// good
var person = new Person();

// not good
delete(obj.attr);

// good
delete obj.attr;

// not good
if (a = 10) {
    a++;
}

// not good
var a = [1, , , 2, 3];

// not good
Var nums = [];

for (var i = 0; i < 10; i++) {
    (function(i) {
        nums[i] =function(j) {
            return i + j;
        };
    }(i));
}

// not good
var singleton = new function() {
    var privateVar;

    this.publicMethod = function() {
        privateVar = 1;
    };

    this.publicMethod2 = function() {
        privateVar = 2;
    };
};

```

雜項

  • 不要混用tabspace
  • 不要在一處使用多個tabspace
  • 換行符統一用'LF';
  • 對上下文this的引用只能使用'_this', 'that', 'self'其中一個來命名;
  • 行尾不要有空白字符;
  • switchfalling throughno default的狀況必定要有註釋特別說明;
  • 不容許有空的代碼塊。

代碼示例:

```js

// not good
var a   =1;

function Person() {
    // not good
    var me = this;

    // good
    var _this = this;

    // good
    var that = this;

    // good
    var self = this;
}

// good
switch (condition) {
    case 1:
    case 2:
            ...
    break;
    case 3:
            ...
    // why fall through
    case 4:
            ...
    break;
    // why no default
}

// not good with empty block
if (condition) {

}

```

相關文章
相關標籤/搜索