# JavaScript 規范
## 目的
遵守公共一致的編碼標準能幫助團隊確保代碼的質量、減少Bug和容易維護。希望大家共同遵守。
>[info] 在一致的環境下,團隊協作中有更高的效率,團隊的成員可以減少犯錯的機會
>[info] 程序員可以方便的了解其他人的代碼,弄清程序的狀況,就和看自己的代碼一樣
## IDE
使用好一款好的編輯器將提升更多的工作效率,比且使用相同的編輯器能減少更多的相容性問題。推薦使用以下兩款編輯器:
`Adobe Brackets` `Sublime Text`


## 文件
### 命名
統一使用小寫字母配合有意義的單詞進行命名,可使用“-”(減號)進行分隔單詞或以`v`開始的版本號。
`meizu.js` `meizu.min.js` `tools-v1.2.min.js`
### 編碼
所有文件統一使用UTF-8無BOM頭文件編碼。

## 通用規范
### 縮進
約定使用4個空格來進行縮進,注意調整編輯器的設定。
### 空行
* 函數聲明之間
~~~
function say() {
...
}
function hello() { ... }
~~~
* 流程語句之間
~~~
if (1 + 1 == 2) {
...
}
for (var i = 1; i < 10; i++) { ... }
~~~
* 不同邏輯之間
* 部分注釋之外
* 較大的程序體之間
### 引號
優先使用`"`(雙引號)來標識字符串,可嵌套`'`(單引號)配合使用,也可使用`\`(正斜線)進行轉義使用。
~~~
var str = "hello world";
var $abc = $(".abc");
var a = "<a href=\"http://www.baidu.com\">baidu</a>";
~~~
### 空格
* 二元運算符左右
~~~
var count = i + k * s;
var str || "abc";
~~~
* 三元運算符左右
~~~
var url = url ? url + "/abc" : url;
~~~
* 流程語句條件左右
* 匿名函數參數左右
* 內置關鍵字右邊
* `;`(分號)右邊
* `:`(冒號)右邊
~~~
if (condition) {
...
} else if () {
...
}
for (var i = 1; i < 10; i++) {
...
}
switch (variable) {
case 1:
...
}
function (id, name) {
...
}
var obj = {name: "hello world!"};
~~~
* `,`(逗號)右邊
~~~
var variable, one = 1, a, b;
get(url, data, callback, failCallback);
~~~
* 有函數名的函數參數右邊
~~~
function funName(id, name) {
...
}
~~~
* 為了對齊而使用的連續空格
~~~
var name = "";
var age = 12;
var sex = 1;
var phone = "135...";
~~~
### 注釋
#### 行注釋
使用`//`接一個`空格`寫上下一行或者下一塊邏輯的說明,行尾注釋注意在`//`前加上一個`空格`。
~~~
// 當前Url
var currentUrl;
~~~
#### 函數注釋
使用`/**`開始`*/`結束,最上面是函數的作用說明,換行后加上參數的注釋與返回的數據注釋,注意`*`(星號)之間的對齊。
~~~
/**
* 獲取驗證碼
*
* @param {function} callback 成功回調函數
* @param {function} failCallback 失敗回調函數
* @return {string} 驗證碼Url
*/
function getVerifyCode(callback, failCallback) {
var url = "/index/captcha";
var data = {refresh: 1};
return _get(url, data, callback, failCallback);
}
~~~
#### 塊注釋
用于區別于其他邏輯的一大段代碼塊使用的注釋,`/*`和`*/`之間左右各用1個`空格`和5個`-`(減號)拼接文字組成。
~~~
/* -----tools----- */
/* -----goods/index----- */
/* -----member/index/index----- */
~~~
## 變量
### 命名
* 使用小駝峰式命名法(lower camel case)
* 使用有意義的英文單詞
* 私有的變量使用“_”(下劃線)開始
>[info] * 作用域不大臨時變量可以簡寫,比如:str,num,bol,obj,fun,arr。
>[info] * 循環變量可以簡寫,比如:i,j,k等。
~~~
name currentUrl _csrf failCallback
~~~
### 聲明與作用域
* 使用`var`關鍵詞聲明局部變量
* 盡量確定變量的作用域而使用`var`關鍵詞來聲明
* 聲明變量的同時應盡量設定變量的類型
* 類似的變量可放在同一行進行聲明
~~~
var list = [];
var data = {};
var name, sex, age = 10;
~~~
### 常用數據類型
JavaScript中有字符串、數字、布爾、數組、對象、Null、Undefined幾種數據類型。
>[info] JavaScript 擁有動態類型。這意味著相同的變量可用作不同的類型
#### 字符串
使用`"`(雙引號)來聲明字符串變量,明確自己需要的變量類型。
正確的
>[success] `var string = "hello world";`
>[success] `var mobile = "13012345678";`
>[success] `var skuKey = "12_25_40";`
>[success] `var skuKey = "";`
錯誤的
>[danger] `var skuKey;` 因為當前實際聲明的是`sku = undefined`在某些具體判斷中會出現預想之外的情況。
#### 數字
JavaScript 只有一種數字類型。數字可以帶小數點,也可以不帶。
>[info] 極大或極小的數字可以通過科學(指數)計數法來書寫。
~~~
var number = 123456;
var number = 1.23;
~~~
#### 布爾
布爾(邏輯)只能有兩個值:`true` 或 `false`,應多使用`is`前綴組合變量名使用。
~~~
var isLogin = false;
var isFlag = true;
~~~
#### 數組
約定使用`[]`(左右中括號)來聲明一個空數組,根據代碼的長度可寫在同一行也可換行,換行寫請注意最后一個元素需要加上`,`(逗號)。
>[info] 在JavaScript中數組只能用數字型下標。
~~~
var music = [];
music[1] = "";
music[2] = "";
var ids = [1, 2, 3];
var complex = [1, 2, ["2-1", "2-2", ["2-2-1"]], 3];
var data = [
"ceui",
"測試",
];
~~~
#### 對象
約定使用`{}`(左右花括號)來聲明一個空對象,根據代碼的長度可寫在同一行也可換行,換行寫請注意最后一個元素需要加上`,`(逗號)。
>[info] 對象不止可以用`.`(點)來操作屬性,還可使用`[]`(左右中括號)數組的方式來操作屬性。
~~~
var object = {};
object.title = "";
alert(object.title);
alert(object[title]);
var music = {title: "aLiEz", author: "xxx"};
var movie = {
title: "",
author: "",
...,
};
~~~
#### Null與Undefined
#### 其他
時間類型
## 函數
### 命名
* 使用小駝峰式命名法(lower camel case)
* 使用有意義的英文單詞
* 私有的函數使用“_”(下劃線)開始
* 使用動詞前綴表示一些行為的函數
~~~
function getList(goodsId) { ... }
function generateAlert(container, text, obj) { ... }
function _checkLogin() { ... }
function _post(a, b, c) { ... }
~~~
### 參數
> 與變量命名規范保持一致。
### 匿名與回調函數
匿名函數可以有效的保證在頁面上寫入JavaScript,而不會造成全局變量的污染。在`()`里寫入匿名函數后再寫一個`()`表示聲明一個匿名函數并執行。
~~~
function () { ... }
(function ($) { ... })(jQuery);
~~~
### 對象字面量(函數參數)
一個對象字面量就是包含在一對花括號中的0個或多個“名/值”對,可減少傳參錯誤的發生。
~~~
function generateAlert(container, text, data) {
var oldData = {
container: container,
place: "append",
type: "info",
message: text,
...
};
// 合并對象,用戶數據覆蓋默認數據
var newData = $.extend({}, oldData, data);
...
}
generateAlert("alert", "hello world", {message: "hehe", type: "warning"});
~~~
### 面向對象書寫方式
使用匿名函數進行封裝,提高重用性。
~~~
(function ($) {
function api() {
}
api.prototype = {
init: function (domain, d) {
this.domain = "//" + domain;
this.d = d;
},
getList: function (id) {
...
},
...
}
// 注冊到全局
window.api = new api;
})(jQuery);
var api = window.api;
api.init("api.shop.com", 10);
var list = api.getList(1);
...
~~~