Web平臺項目開發(fā)規(guī)范文檔

數(shù)字動力Web平臺項目開發(fā)規(guī)范

一、目的

本文檔編寫旨在公司W(wǎng)eb平臺軟件開發(fā)人員在項目開發(fā)上提供參考和統(tǒng)一標(biāo)準(zhǔn)。

二、項目規(guī)范

1、命名規(guī)則

1.1、項目命名

全部采用小寫方式, 以下劃線分隔。

例:my_project_name、dp_esa_web、dp_cbell_web

1.2、目錄命名

參照項目命名規(guī)則;

有復(fù)數(shù)結(jié)構(gòu)時,要采用復(fù)數(shù)命名法。

例:scripts, styles, images, data_models

1.3、JS文件命名

參照項目命名規(guī)則。

例:account_model.js

1.4、CSS, SCSS文件命名

參照項目命名規(guī)則。

例:retina_sprites.scss

1.5、HTML文件命名

參照項目命名規(guī)則。

例:error_report.html

2、項目結(jié)構(gòu)

2.1、React
2.2、TDesign
2.3、Ant Design Pro
2.4、Vue

三、代碼規(guī)范

1、HTML

1.1、語法
  • 縮進使用soft tab(4個空格);
  • 嵌套的節(jié)點應(yīng)該縮進;
  • 在屬性上,使用雙引號,不要使用單引號;
  • 屬性名全小寫,用中劃線做分隔符;
  • 不要在自動閉合標(biāo)簽結(jié)尾處使用斜線(HTML5 規(guī)范 指出他們是可選的);
  • 不要忽略可選的關(guān)閉標(biāo)簽,例:</li></body>。

<!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>

1.2、HTML5 doctype

在頁面開頭使用這個簡單地doctype來啟用標(biāo)準(zhǔn)模式,使其在每個瀏覽器中盡可能一致的展現(xiàn);

雖然doctype不區(qū)分大小寫,但是按照慣例,doctype大寫 (關(guān)于html屬性,大寫還是小寫)。


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

1.3、lang屬性

根據(jù)HTML5規(guī)范:

應(yīng)在html標(biāo)簽上加上lang屬性。這會給語音工具和翻譯工具幫助,告訴它們應(yīng)當(dāng)怎么去發(fā)音和翻譯。

更多關(guān)于 lang 屬性的說明在這里;

在sitepoint上可以查到語言列表;

但sitepoint只是給出了語言的大類,例如中文只給出了zh,但是沒有區(qū)分香港,臺灣,大陸。而微軟給出了一份更加詳細的語言列表,其中細分了zh-cn, zh-hk, zh-tw。


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

1.4、字符編碼

通過聲明一個明確的字符編碼,讓瀏覽器輕松、快速的確定適合網(wǎng)頁內(nèi)容的渲染方式,通常指定為'UTF-8'。


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

1.5、IE兼容模式

<meta> 標(biāo)簽可以指定頁面應(yīng)該用什么版本的IE來渲染;

如果你想要了解更多,請點擊這里

不同doctype在不同瀏覽器下會觸發(fā)不同的渲染模式(這篇文章總結(jié)的很到位)。


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

1.6、引入CSS, JS

根據(jù)HTML5規(guī)范, 通常在引入CSS和JS時不需要指明 type,因為 text/csstext/javascript 分別是他們的默認值。

HTML5 規(guī)范鏈接


<!-- 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>

1.7、屬性順序

屬性應(yīng)該按照特定的順序出現(xiàn)以保證易讀性;

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

class是為高可復(fù)用組件設(shè)計的,所以應(yīng)處在第一位;

id更加具體且應(yīng)該盡量少使用,所以將它放在第二位。


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

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

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

1.8、boolean屬性

boolean屬性指不需要聲明取值的屬性,XHTML需要每個屬性聲明取值,但是HTML5并不需要;

更多內(nèi)容可以參考 WhatWG section on boolean attributes

boolean屬性的存在表示取值為true,不存在則表示取值為false。


<input type="text" disabled>

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

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

1.9、JS生成標(biāo)簽

在JS文件中生成標(biāo)簽讓內(nèi)容變得更難查找,更難編輯,性能更差。應(yīng)該盡量避免這種情況的出現(xiàn)。

1.10、減少標(biāo)簽數(shù)量

在編寫HTML代碼時,需要盡量避免多余的父節(jié)點;

很多時候,需要通過迭代和重構(gòu)來使HTML變得更少。


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

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

1.11、實用高于完美

盡量遵循HTML標(biāo)準(zhǔn)和語義,但是不應(yīng)該以浪費實用性作為代價;

任何時候都要用盡量小的復(fù)雜度和盡量少的標(biāo)簽來解決問題。

2、CSS, SCSS

2.1、縮進

使用soft tab(4個空格)。


.element {
    position: absolute;
    top: 10px;
    left: 10px;

    border-radius: 10px;
    width: 50px;
    height: 50px;
}

2.2、分號

每個屬性聲明末尾都要加分號。


.element {
    width: 20px;
    height: 20px;

    background-color: red;
}

2.3、空格

以下幾種情況不需要空格:

  • 屬性名后
  • 多個規(guī)則的分隔符,
  • !important !
  • 屬性值中(后和)
  • 行末不要有多余的空格

/* 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 {

}

以下幾種情況需要空格:

  • 屬性值前
  • 選擇器>, +, ~前后
  • {
  • !important !
  • @else 前后
  • 屬性值中的,
  • 注釋/*后和*/

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

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

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

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

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

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

2.4、空行

以下幾種情況需要空行:

  • 文件最后保留一個空行
  • }后最好跟一個空行,包括scss中嵌套的規(guī)則
  • 屬性之間需要適當(dāng)?shù)目招?,具體見屬性聲明順序

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

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

.dialog {
    color: red;

    &:after {
        ...
    }
}

2.5、換行

以下幾種情況不需要換行:

  • {

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

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

以下幾種情況需要換行:

  • {后和}
  • 每個屬性獨占一行
  • 多個規(guī)則的分隔符,
/* not good */
.element, .dialog {
    ...
}

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

2.6、注釋

注釋統(tǒng)一用/* */(scss中也不要用//),具體參照右邊的寫法;

縮進與下一行代碼保持一致;

可位于一個代碼行的末尾,與代碼間隔一個空格。


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

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

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

    color: red; /* color red */
}

2.7、引號

最外層統(tǒng)一使用雙引號;

url的內(nèi)容要用引號;

屬性選擇器中的屬性值需要引號。


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

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

2.8、命名
  • 類名使用小寫字母,以中劃線分隔
  • id采用駝峰式命名
  • scss中的變量、函數(shù)、混合、placeholder采用駝峰式命名

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

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

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

/* 函數(shù) */
@function pxToRem($px) {
    ...
}

/* 混合 */
@mixin centerBlock {
    ...
}

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

2.9、屬性聲明順序

相關(guān)的屬性聲明按右邊的順序做分組處理,組之間需要有一個空行。


.declaration-order {
    display: block;
    float: right;

    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;

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

    font: normal 13px "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"
    ]
]

2.10、顏色

顏色16進制用小寫字母;

顏色16進制盡量用簡寫。


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

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

2.11、屬性簡寫

屬性簡寫需要你非常清楚屬性值的正確順序,而且在大多數(shù)情況下并不需要設(shè)置屬性簡寫中包含的所有值,所以建議盡量分開聲明會更加清晰;

marginpadding 相反,需要使用簡寫;

常見的屬性簡寫包括:

  • font
  • background
  • transition
  • animation

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

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

2.12、媒體查詢

盡量將媒體查詢的規(guī)則靠近與他們相關(guān)的規(guī)則,不要將他們一起放到一個獨立的樣式文件中,或者丟在文檔的最底部,這樣做只會讓大家以后更容易忘記他們


.element {
    ...
}

.element-avatar{
    ...
}

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

    .element-avatar {
        ...
    }
}

2.13、SCSS相關(guān)

提交的代碼中不要有 @debug

聲明順序:

  • @extend
  • 不包含 @content@include
  • 包含 @content@include
  • 自身屬性
  • 嵌套規(guī)則

@import 引入的文件不需要開頭的_和結(jié)尾的.scss;

嵌套最多不能超過5層;

@extend 中使用placeholder選擇器;

去掉不必要的父級引用符號&。


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

/* good */
@import "dialog";

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

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

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

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

2.14、雜項

不允許有空的規(guī)則;

元素選擇器用小寫字母;

去掉小數(shù)點前面的0

去掉數(shù)字中不必要的小數(shù)點和末尾的0;

屬性值0后面不要加單位;

同個屬性不同前綴的寫法需要在垂直方向保持對齊,具體參照右邊的寫法;

無前綴的標(biāo)準(zhǔn)屬性應(yīng)該寫在有前綴的屬性后面;

不要在同個規(guī)則里出現(xiàn)重復(fù)的屬性,如果重復(fù)的屬性是連續(xù)的則沒關(guān)系;

不要在一個文件里出現(xiàn)兩個相同的規(guī)則;

border: 0; 代替 border: none;

選擇器不要超過4層(在scss中如果超過4層應(yīng)該考慮用嵌套的方式來寫);

發(fā)布的代碼中不要有 @import;

盡量少用'*'選擇器。


/* 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, #fff 0, #eee 100%);
    background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
    background: -moz-linear-gradient(top, #fff 0, #eee 100%);
}

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

    background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
    background:    -moz-linear-gradient(top, #fff 0, #eee 100%);
    background:         linear-gradient(to bottom, #fff 0, #eee 100%);
}

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

3、JavaScript

3.1、縮進

使用soft tab(4個空格)


var x = 1,
    y = 1;

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

3.2、單行長度

不要超過80,但如果編輯器開啟word wrap可以不考慮單行長度。

3.3、分號

以下幾種情況后需加分號:

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

/* var declaration */
var x = 1;

/* expression statement */
x++;

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

3.4、空格

以下幾種情況不需要空格:

  • 對象的屬性名后
  • 前綴一元運算符后
  • 后綴一元運算符前
  • 函數(shù)調(diào)用括號前
  • 無論是函數(shù)聲明還是函數(shù)表達式,(前不要空格
  • 數(shù)組的[后和]
  • 對象的{后和}
  • 運算符(后和)

以下幾種情況需要空格:

  • 二元運算符前后
  • 三元運算符?:前后
  • 代碼塊{
  • 下列關(guān)鍵字前:else, while, catch, finally
  • 下列關(guān)鍵字后:if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof
  • 單行注釋//后(若單行注釋和代碼同行,則//前也需要),多行注釋*
  • 對象的屬性值前
  • for循環(huán),分號后留有一個空格,前置條件如果有多個,逗號后留一個空格
  • 無論是函數(shù)聲明還是函數(shù)表達式,{前一定要有空格
  • 函數(shù)的參數(shù)之間

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

3.5、空行

以下幾種情況需要空行:

  • 變量聲明后(當(dāng)變量聲明在代碼塊的最后一行時,則無需空行)
  • 注釋前(當(dāng)注釋在代碼塊的第一行時,則無需空行)
  • 代碼塊后(在函數(shù)調(diào)用、數(shù)組、對象中則無需空行)
  • 文件最后保留一個空行

// 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() {
        return 1;
    },

    bar: function() {
        return 2;
    }
};

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

3.6、換行

換行的地方,行末必須有,或者運算符;

以下幾種情況不需要換行:

  • 下列關(guān)鍵字后:else, catch, finally
  • 代碼塊{

以下幾種情況需要換行:

  • 代碼塊{后和}
  • 變量賦值后

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

3.7、單行注釋

雙斜線后,必須跟一個空格;

縮進與下一行代碼保持一致;

可位于一個代碼行的末尾,與代碼間隔一個空格。


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

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

3.8、多行注釋

最少三行, *后跟一個空格,具體參照右邊的寫法;

建議在以下情況下使用:

  • 難于理解的代碼段
  • 可能存在錯誤的代碼段
  • 瀏覽器特殊的HACK代碼
  • 業(yè)務(wù)邏輯強相關(guān)的代碼

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

3.9、文檔注釋

各類標(biāo)簽@param, @method等請參考usejsdocJSDoc Guide;

建議在以下情況下使用:

  • 所有常量
  • 所有函數(shù)
  • 所有類

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

3.10、引號

最外層統(tǒng)一使用單引號。


// not good
var x = "test";

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

3.11、變量命名
  • 標(biāo)準(zhǔn)變量采用駝峰式命名(除了對象的屬性外,主要是考慮到cgi返回的數(shù)據(jù))
  • ID在變量名中全大寫
  • URL在變量名中全大寫
  • Android在變量名中大寫第一個字母
  • iOS在變量名中小寫第一個,大寫后兩個字母
  • 常量全大寫,用下劃線連接
  • 構(gòu)造函數(shù),大寫第一個字母
  • 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');

3.12、變量聲明

一個函數(shù)作用域中所有的變量聲明盡量提到函數(shù)首部,用一個var聲明,不允許出現(xiàn)兩個連續(xù)的var聲明。


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

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

3.13、函數(shù)

無論是函數(shù)聲明還是函數(shù)表達式,'('前不要空格,但'{'前一定要有空格;

函數(shù)調(diào)用括號前不需要空格;

立即執(zhí)行函數(shù)外必須包一層括號;

不要給inline function命名;

參數(shù)之間用', '分隔,注意逗號后有一個空格。


// 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() {
    return 1;
})();

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

3.14、數(shù)組、對象

對象屬性名不需要加引號;

對象以縮進的形式書寫,不要寫在一行;

數(shù)組、對象最后不要有逗號。


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

var a = {b: 1};

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

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

3.15、括號

下列關(guān)鍵字后必須有大括號(即使代碼塊的內(nèi)容只有一行):if, else, for, while, do, switch, try, catch, finally, with。


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

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

3.16、null

適用場景:

  • 初始化一個將來可能被賦值為對象的變量
  • 與已經(jīng)初始化的變量做比較
  • 作為一個參數(shù)為對象的函數(shù)的調(diào)用傳參
  • 作為一個返回對象的函數(shù)的返回值

不適用場景:

  • 不要用null來判斷函數(shù)調(diào)用時有無傳參
  • 不要與未初始化的變量做比較

// 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) {
    ...
}

3.17、undefined

永遠不要直接使用undefined進行變量判斷;

使用typeof和字符串'undefined'對變量進行判斷。


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

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

3.18、shint

===, !==代替==, !=

for-in里一定要有hasOwnProperty的判斷;

不要在內(nèi)置對象的原型上添加方法,如Array, Date;

不要在內(nèi)層作用域的代碼里聲明了變量,之后卻訪問到了外層作用域的同名變量;

變量不要先使用后聲明;

不要在一句代碼中單單使用構(gòu)造函數(shù),記得將其賦值給某個變量;

不要在同個作用域下聲明同名變量;

不要在一些不需要的地方加括號,例:delete(a.b)

不要使用未聲明的變量(全局變量需要加到.jshintrc文件的globals屬性里面);

不要聲明了變量卻不使用;

不要在應(yīng)該做比較的地方做賦值;

debugger不要出現(xiàn)在提交的代碼里;

數(shù)組中不要存在空元素;

不要在循環(huán)內(nèi)部聲明函數(shù);

不要像這樣使用構(gòu)造函數(shù),例:new function () { ... }, new Object;


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

3.19、雜項

不要混用tab和space;

不要在一處使用多個tab或space;

換行符統(tǒng)一用LF

對上下文this的引用只能使用_this, that, self其中一個來命名;

行尾不要有空白字符;

switch的falling through和no default的情況一定要有注釋特別說明;

不允許有空的代碼塊


// 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) {

}

四、參考文章

Code Guide by @AlloyTeam

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、 目錄結(jié)構(gòu) 二、 UI框架選擇 PC端Vue項目UI框架優(yōu)先選擇:Element UI、iView移動端Vue...
    zhudying閱讀 4,693評論 4 27
  • Web前端開發(fā)規(guī)范文檔 規(guī)范目的: 使開發(fā)流程更加規(guī)范化。 通用規(guī)范: TAB鍵用兩個空格代替(WINDOWS下T...
    蕎葉閱讀 565評論 0 1
  • 一.規(guī)范目的 使開發(fā)流程更加規(guī)范化。 二.通用規(guī)范 TAB鍵用兩個空格代替(WINDOWS下TAB鍵占四個空格,L...
    overflow_hidden閱讀 2,513評論 0 0
  • 基本準(zhǔn)則 符合web標(biāo)準(zhǔn),html語義化;html,css,JavaScript分離;代碼簡潔有序,盡可能減少冗余...
    喵嗚君閱讀 873評論 0 1
  • 前言 本開發(fā)規(guī)范基于《阿里巴巴Java開發(fā)手冊終極版》修改,并集成我們自己的項目開發(fā)規(guī)范,整合而成。 為表示對阿里...
    4ea0af17fd67閱讀 5,749評論 0 5

友情鏈接更多精彩內(nèi)容