前端程式碼風格

NO IMAGE

檔名

均採用小寫方式, 以中劃線分隔, 如有複數結構時,採用複數命名法

  • 目錄名:scripts,styles,images,data-models

  • 檔名: example.js retina-sprites.css

Javascript

註釋

何時使用

  • 難於理解的程式碼段

  • 可能存在錯誤的程式碼段

  • 瀏覽器特殊的HACK程式碼

  • 想吐槽的產品邏輯, 合作同事

  • 業務邏輯強相關的程式碼

// 單行註釋斜槓後面要留有一個空格
/*
* 多行註釋最少三行,註釋內容與星標前保留一個空格
*/
var hello = '';        // 描述變數可以這樣寫在變數右邊
/*
* 描述方法(函式)必須使用多行描述
* 如有必要可以加上引數和返回值說明,參考 http://usejsdoc.org/
* @param {Object} balabalabala
* @return {Object} balabalabala
*/
function foo() {
// 描述下面程式碼時做什麼的,方法第一行不需要留空格
doSomething();
// 描述下面程式碼時做什麼的,上方需要留一個空行
afterDoSomething();
if (flag) {
// 描述下面程式碼時做什麼的,程式碼塊的第一行也不需要留空格
drive();
}
}

語法

  • 使用四個空格的 soft tabs — 這是保證程式碼在各種環境下顯示一致的唯一方式。

  • 一般情況下 有關鍵字的地方都要有空格

  • 字串使用單引號而不是雙引號:`var str = ‘hello world’;`

  • 單行長度,理論上不要超過80列,不過如果編輯器開啟 soft wrap 的話可以不考慮單行長度

  • 接上一條,如果需要換行,存在操作符的情況,一定在操作符後換行,然後換的行縮排4個空格

  • 這裡要注意,如果是多次換行的話就沒有必要繼續縮排了,比如說下面這種就是最佳格式。

if (typeof qqfind === "undefined" ||
typeof qqfind.cdnrejected === "undefined" ||
qqfind.cdnrejected !== true) {
url = "http://pub.idqqimg.com/qqfind/js/location4.js";
} else {
url = "http://find.qq.com/js/location4.js";
}

建立Object物件

// Bad
var team = new Team();
team.title = "AlloyTeam";
team.count = 25;
// Good  
var team = {
title: "AlloyTeam",        // 冒號後需要跟一個空格
count: 25
};

建立Array物件

// Bad
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);
// Good
var colors = [ "red", "green", "blue" ];  // 中括號左右均需要一個空格
var numbers = [ 1, 2, 3, 4 ];

建構函式

/**
* 建立一個建構函式
*/
function Modal(options) {    // 函式名使用大寫字母開頭,駝峰式命名
this.width = options.width;    // 屬性在建構函式體中定義
this.height = options.height;
}
Modal.prototype.show = function() {    // 方法定義在原型鏈上
// show
}
Modal.prototype.hide = function() {
// hide
}
// 例項化物件
var modal = new Modal({
width: 200,
height: 300
});

if 語法

// if else 前後留有空格,
if (flag) {
} else {
}

for 語法

// 普通for
var values = [ 1, 2, 3, 4, 5, 6, 7 ],
i, len;
for (i=0, len=values.length; i<len; i  ) {
process(values[i]);
}
// for in, (一般情況下不要用for in)
var prop;
for (prop in object) {
// 注意這裡一定要有 hasOwnProperty 的判斷,不要把原型鏈上的屬性列舉出來
if (object.hasOwnProperty(prop)) {
console.log("Property name is "   prop);
console.log("Property value is "   object[prop]);
}
}

switch 語法

// switch和括號之間有空格, case需要縮排, break之後跟下一個case中間留一個空行
switch (condition) {
case "first":
// code
break;
case "third":
// code
break;
default:
// code
}
// 沒有default的情況需要註釋特別說明
switch(condition) {
case "first":
// code
break;
case "second":
// code
break;
// no default
}

宣告

變數宣告

var _body = $(document.body); // 全域性變數使用下劃線 _ 開頭
function foo() {
var result,    // 一個程式碼塊裡的變數宣告只用一個var
length,    // 一個變數一行,行末跟註釋
mainWrap;// 駝峰式命名法
}

常量宣告

使用全大寫字母+下劃線的命名方式方式

var IMAGE_DOMAIN = 'WWW.XXX.COM';     

函式宣告

  • 函式宣告統一使用function命令進行宣告

// good
function foo() {        // 小括號前不需要空格,小括號與大括號間需要一個空格
doSomething(); // 函式呼叫括號前後不需要空格
return "hello world";
}
// bad
var foo = function() {
return "hello world";
}
// bad
var foo = new Function(
'return "hello world"'
);
  • 立即執行函式的寫法, 最外層必須包一層括號

// Good
(function() {
"use strict";    // 使用嚴格模式
function doSomething() {
// code
}
function doSomethingElse() {
// code
}
})();

空行

說明:下面程式碼中的註釋處代表著實際程式碼中的空行

function foo1() {
}
// 方法之間加空行
function foo2() {
}
// 邏輯塊與方法之間加空行增加可讀性
for (var i=0; i<10; i  ) {
} 
// 邏輯塊之間加空行增加可讀性
if (flag) {
} else {
}
// 檔案結尾留一個空行

雜項

  • 只有字串型別允許使用 == !=,如if(x == 'a') 其他情況一律用嚴格比較條件 === !==

  • eval 非特殊業務, 禁用!!!

  • with 非特殊業務, 禁用!!!

CSS

語法

  • 使用組合選擇器時,保持每個獨立的選擇器佔用一行。

  • 為了程式碼的易讀性,在每個宣告的左括號前增加一個空格。

  • 宣告塊的右括號應該另起一行。

  • 每條宣告 : 後應該插入一個空格。

  • 每條宣告應該只佔用一行來保證錯誤報告更加準確。

  • 所有宣告應該以分號結尾。雖然最後一條宣告後的分號是可選的,但是如果沒有他,你的程式碼會更容易出錯。

  • 逗號分隔的取值,都應該在逗號之後增加一個空格。比如說box-shadow

  • 不要在顏色值 rgb() rgba() hsl() hsla()和 rect() 中增加空格

  • 不要帶有取值前面不必要的 0 (比如,使用 .5 替代 0.5)。

  • 所有的十六進位制值都應該使用小寫字母,例如 #fff。因為小寫字母有更多樣的外形,在瀏覽文件時,他們能夠更輕鬆的被區分開來。

  • 為選擇器中的屬性取值新增引號,例如 input[type=”text”]。 他們只在某些情況下可有可無,所以都使用引號可以增加一致性。

  • 不要為 0 指明單位,比如使用 margin: 0; 而不是 margin: 0px;。

/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {
padding: 15px;
margin: 0px 0px 15px;
background-color: rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 2px #C0C0C0, inset 0 1px 0 #F8F8F8
}
/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {
padding: 15px;
margin-bottom: 15px;
background-color: rgba(0,0,0,.5);
box-shadow: 0 1px 2px #c0c0c0, inset 0 1px 0 #f8f8f8;
}

宣告順序

相關的屬性宣告應該以下面的順序分組處理:

  1. Positioning

  2. Box model 盒模型

  3. Typographic 排版

  4. Visual 外觀

Positioning 處在第一位,因為他可以使一個元素脫離正常文字流,並且覆蓋盒模型相關的樣式。盒模型緊跟其後,因為他決定了一個元件的大小和位置。

其他屬性只在元件 內部 起作用或者不會對前面兩種情況的結果產生影響,所以他們排在後面。

關於完整的屬性以及他們的順序,請參考 Recess

.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;
/* Misc */
opacity: 1;
}

Class 命名

  • 保持 Class 命名為全小寫,可以使用短劃線(不要使用下劃線和 camelCase 命名)。短劃線應該作為相關類的自然間斷。(例如,.btn.btn-danger)。

  • 避免過度使用簡寫。.btn 可以很好地描述 button,但是 .s 不能代表任何元素。

  • 使用 .js-* classes 來表示行為(相對於樣式),但是不要在 CSS 中包含這些 classes。

/* Bad example */
.t { ... }
.red { ... }
.header { ... }
/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }

選擇器

  • 使用 classes 而不是通用元素標籤來優化渲染效能。

  • 避免在經常出現的元件中使用一些屬性選擇器 (例如,[class^=”…”])。瀏覽器效能會受到這些情況的影響。

  • 減少選擇器的長度,每個組合選擇器選擇器的條目應該儘量控制在 3 個以內。

  • 只在必要的情況下使用後代選擇器 (例如,沒有使用帶字首 classes 的情況).

/* Bad example */
span { ... }
.page-container #stream .stream-item .tweet .tweet-header .username { ... }
.avatar { ... }
/* Good example */
.avatar { ... }
.tweet-header .username { ... }
.tweet .avatar { ... }

不要使用 @import

<link> 標籤相比,@import 指令要慢很多,不光增加了額外的請求次數,還會導致不可預料的問題。替代辦法有以下幾種:

  • 使用多個 <link> 元素

  • 通過 Sass 或 Less 類似的 CSS 前處理器將多個 CSS 檔案編譯為一個檔案

HTML

語法

  • 用兩個空格來代替製表符(tab) — 這是唯一能保證在所有環境下獲得一致展現的方法。

  • 在屬性上,使用雙引號,不要使用單引號。

  • 不要在自動閉合標籤結尾處使用斜線 – HTML5 規範 指出他們是可選的。

  • 不要忽略可選的關閉標籤(例如,</li> 和 </body>)。

  • 巢狀的節點應該縮排(四個空格)。

字元編碼

通過明確宣告字元編碼,能夠確保瀏覽器快速並容易的判斷頁面內容的渲染方式。這樣做的好處是,可以避免在 HTML 中使用字元實體標記(character entity),從而全部與文件編碼一致(一般採用 UTF-8 編碼)。

引入 CSS 和 JavaScript

根據 HTML5 規範, 通常在引入 CSS 和 JavaScript 時不需要指明 type,因為 text/css 和 text/javascript 分別是他們的預設值。

屬性順序

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

  • class

  • id

  • name

  • data-*

  • src, for, type, href, value , max-length, max, min, pattern

  • placeholder, title, alt

  • aria-*, role

  • required, readonly, disabled

Classes 是為高可複用元件設計的,理論上他們應處在第一位。Ids 更加具體而且應該儘量少使用(例如, 頁內書籤),所以他們處在第二位。

不要用JavaScript 生成標籤

在 JavaScript 檔案中生成標籤讓內容變得更難查詢,更難編輯,效能更差。應該儘量避免這種情況的出現。

示例程式碼


<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- External CSS -->
<link rel="stylesheet" href="code-guide.css">
<!-- In-document CSS -->
<style>
/* ... */
</style>
</head>
<body>
<a id="..." class="..." data-modal="toggle" href="#">
Example link
</a>
<input class="form-control" type="text">
<img src="..." alt="...">
<!-- JavaScript -->
<script src="code-guide.js"></script>
</body>
</html>