前端開發 JavaScript 規範文檔

一,規範目的

爲提升團隊協做效率,便於前端後期優化維護,輸出高質量的文檔。javascript

 

2、基本準則

  • 符合web標準,結構表現行爲分離,兼容性優良。頁面性能方面,代碼要求簡潔明瞭有序, 儘量的減少服務器負載,保證最快的解析速度。
  • 項目的維護和二次開發多是直接或間接的團隊合做,因此建立易維護的代碼是一個項目成功與否的關鍵,易維護的代碼意味着具備以下特性:
    • 閱讀性好:如良好的註釋和命名規範,有文檔
    • 具備一致性:看起來如同一我的編寫
    • 代碼的鬆耦合,高度模塊化:將頁面內的元素視爲一個個模塊,相互獨立,儘可能避免耦合太高的代碼,從html,css,js三個層面都要考慮模塊化
    • 嚴格按照規範編寫代碼

 

3、命名規範

一、目的css

提升代碼可預測性和可維護性的方法是使用命名約定,這就意味着採用一致的方法來對變量和函數進行命名。html

 

二、變量名前端

變量名包括全局變量,局部變量,類變量,函數參數。java

 

三、構造函數(類)命名web

首字母大寫,駝峯式命名。ajax

JS中沒有類,可是能夠用new調用構造函數:var man = new Person()json

 

四、普通變量命名數組

首字母小寫,駝峯式命名,匈牙利命名緩存

如:nCheckCount 表示整形的數值

 

五、匈牙利命名

匈牙利命名法語法:變量名=類型+對象描述

  • 類型指變量的類型
  • 對象描述指對象名字全稱或名字的一部分,要求有明確含義,命名要容易記憶容易理解。

提示: 雖然JavaScript變量表面上沒有類型,可是JavaScript內部仍是會爲變量賦予相應的類型

變量起名類型 變量起名前綴 舉例
Array 數組 a aList, aGroup
Boolean 邏輯 b bChecked
Function 函數 f fInit
Integer 數字 n nTotal
Object 對象 o oButton
Regular Expression 正則 r rEmail
String 字符 s sHtml

 

 

六、其餘前綴規範

可根據團隊及項目須要增長

  • $:表示Jquery對象

    例如:$Content,$Module,一種比較普遍的Jquery對象變量命名規範。

  • fn:表示函數

    例如:fnGetName,fnSetAge;和上面函數的前綴略有不一樣,改用fn來代替,我的認爲fn可以更好的區分普通變量和函數變量。

 

七、例外狀況 

以根據項目及團隊須要,設計出針對項目須要的前綴規範,從而達到團隊開發協做便利的目的。

  • 做用域不大臨時變量能夠簡寫,好比:str,num,bol,obj,fun,arr。
  • 循環變量能夠簡寫,好比:i,j,k等。
  • 某些做爲不容許修改值的變量認爲是常量,所有字母都大寫。例如:COPYRIGHT,PI。常量能夠存在於函數中,也能夠存在於全局。必須採用全大寫的命名,且單詞以_分割,常量一般用於ajax請求url,和一些不會改變的數據。

 

八、函數命名

普通函數:首字母小寫,駝峯式命名,統一使用動詞或者動詞+名詞形式

例如:fnGetVersion(),fnSubmitForm(),fnInit();涉及返回邏輯值的函數可使用is,has,contains等表示邏輯的詞語代替動詞,例如:fnIsObject(),fnHasClass(),fnContainsElment()。

內部函數:使用_fn+動詞+名詞形式,內部函數必需在函數最後定義。

例如:

function fnGetNumber(nTotal) {
    if (nTotal < 100) {
        nTotal = 100;
    }
    return _fnAdd(nTotal);

    function _fnAdd(nNumber) {
        nNumber++;
        return nNumber;
    }
}
alert(fGetNumber(10)); //alert 101

 

對象方法與事件響應函數:對象方法命名使用fn+對象類名+動詞+名詞形式;

例如: fnAddressGetEmail()

 

事件響應函數:fn+觸發事件對象名+事件名或者模塊名

例如:fnDivClick(),fnAddressSubmitButtonClick()

 

函數方法經常使用的動詞

get 獲取/set 設置,
add 增長/remove 刪除
create 建立/destory 移除
start 啓動/stop 中止
open 打開/close 關閉,
read 讀取/write 寫入
load 載入/save 保存,
create 建立/destroy 銷燬
begin 開始/end 結束,
backup 備份/restore 恢復
import 導入/export 導出,
split 分割/merge 合併
inject 注入/extract 提取,
attach 附着/detach 脫離
bind 綁定/separate 分離,
view 查看/browse 瀏覽
edit 編輯/modify 修改,
select 選取/mark 標記
copy 複製/paste 粘貼,
undo 撤銷/redo 重作
insert 插入/delete 移除,
add 加入/append 添加
clean 清理/clear 清除,
index 索引/sort 排序
find 查找/search 搜索,
increase 增長/decrease 減小
play 播放/pause 暫停,
launch 啓動/run 運行
compile 編譯/execute 執行,
debug 調試/trace 跟蹤
observe 觀察/listen 監聽,
build 構建/publish 發佈
input 輸入/output 輸出,
encode 編碼/decode 解碼
encrypt 加密/decrypt 解密,
compress 壓縮/decompress 解壓縮
pack 打包/unpack 解包,
parse 解析/emit 生成
connect 鏈接/disconnect 斷開,
send 發送/receive 接收
download 下載/upload 上傳,
refresh 刷新/synchronize 同步
update 更新/revert 復原,
lock 鎖定/unlock 解鎖
check out 簽出/check in 簽入,
submit 提交/commit 交付
push 推/pull 拉,
expand 展開/collapse 摺疊
begin 起始/end 結束,
start 開始/finish 完成
enter 進入/exit 退出,
abort 放棄/quit 離開
obsolete 廢棄/depreciate 廢舊,
collect 收集/aggregate 彙集

 

九、變量命名例子

(1).爲何須要這樣強制定義變量前綴?正式由於javascript是弱語言形成的。在定義大量變量的時候,咱們須要很明確的知道當前變量是什麼屬性,若是隻經過普通單詞,是很難區分的。

普通代碼

var checked = false;
var check = function() {
    return true;
}
/**
some code
**/

if(check) {//已經沒法很確切知道這裏是要用checked仍是check()從而致使邏輯錯誤
    //do some thing
}

 規範後代碼

var bChecked = false;
var fnCheck = function() {
    return true;
}
/**
some code
**/

if(bChecked) {
    // do some thing
}
if(fnCheck()) {
    // do other thing
}

 

(2).如何標明私有方法或私有屬性?

var person = {
    getName: function () {
        return this._getFirst() + ' ' + this._getLast();
    },
    _getFirst: function () {
        //...
    },
    _getLast: function (){
        //...
    } 
};

在這個例子中,getName()覺得這這是API的一個公開的方法,而_getFirst()和_getLast()意味着這是一個私有函數。儘管他們都是普通的公開方法,可是使用下劃線前綴的表示方法能夠提醒使用person對象的用戶,告訴他們這些方法在其餘地方不能確保必定可以正常工做,不能直接調用。

 

(3).總結:下面是一些使用下劃線約定的變量

  • 使用下劃線結尾來代表是私有變量,例如name_和getElements_()。
  • 使用一個下劃線前綴來表示受保護屬性,使用兩個下劃線前綴來表示私有屬性。

 

 

4、編寫註釋

(1)、公共組件維護者和各欄目WD都須要在文件頭部加上註釋說明:

/**
*文件用途說明
*做者姓名、聯繫方式(旺旺)
*製做日期
**/

 

(2)、大的模塊註釋方法:

//================
// 代碼用途
//================

 

(3)、小的註釋:

//代碼說明

註釋單獨一行,不要在代碼後的同一行內加註釋。

 

 

5、使用空格

使用空格有助於改善代碼的可讀性和一致性。

用處一:

  • 在分開for循環的各個部分的分號以後:例如,for (var i = 0; i < 10; i +=1){…}
  • 在for循環中初始化多個變量(i和最大值等):for (var i = 0, max = 10; i < max; i += 1){…}
  • 在限定數組項的逗號後面:var a = [1, 2, 3];
  • 對象屬性的逗號以後和將屬性名和屬性值分開的冒號以後:var o = {a: 1, b: 2};
  • 分隔開函數中各個參數的逗號以後:myFunc(a, b, c)
  • 在函數聲明的大括號以前:function myFunc() {}
  • 在匿名函數表達式以後:var myFunc = function () {};

 

用處二:

空格的另一個很好的用途是用來分隔全部的操做符和操做,這也就是意味着在 +, -, *, =, <, >, <=, >=, ===, !==, &&, ||, += 等以後使用空格:

//大量空格,而且使用一致,是的代碼可讀性更好
//容許在閱讀的時候不用一口氣讀下去
var d = 0,
    a = b +1;
if ( a && b && c) {
    d = a % c;
    a += d;
}

//反模式
//缺乏空格或空格使用不一致,使得代碼比較混亂
var d= 0;
    a =b+1;
if (a&& b&& c) {
d=a %c;
    a+= d;
}

 

6、編寫 API 文檔

編寫 API 文檔的目的:

  • 爲API編寫註釋不只僅是一中提供參考文檔的簡便方法,並且還有其餘用途——經過再次審查代碼,提升代碼質量。
  • 在解決問題時寫出的解決方案僅僅是一個初稿。該解決方案能夠給出使人期待的輸出,可是該方案是不是最佳方案呢?改代碼是否可讀、易於理解、維護和升級呢?當您再次審視代碼時您將更加肯定代碼哪些部分能夠改進——如何使得代碼更容易繼續更新,移除一些不足之處等。它能夠極大地幫助您建立高質量的代碼。

 

簡單舉例:

/**
* 翻轉一個字符串
*
* @param  {String} 輸入須要翻轉的字符串
* @return {String} 翻轉後的字符串
**/

var reverse = function (input) {
    //...
    return output;
};

 

 

7、推薦寫法

一、除了三目運算,if,else等禁止簡寫

 // 正確的書寫
 if (true) {
     alert(name);
 }
 console.log(name);


 // 不推薦的書寫
 if (true)
     alert(name);
 console.log(name);


 // 不推薦的書寫
 if (true)
 alert(name);
 console.log(name)

 

二、在須要以{}閉合的代碼段前增長換行,如:for if

 // 沒有換行,小的代碼段沒法區分
 if (wl && wl.length) {
     for (i = 0, l = wl.length; i < l; ++i) {
         p = wl[i];
         type = Y.Lang.type(r[p]);
         if (s.hasOwnProperty(p)) {
             if (merge && type == 'object') {
                 Y.mix(r[p], s[p]);
             } else if (ov || !(p in r)) {
                 r[p] = s[p];
             }
         }
     }
 }


 // 有了換行,邏輯清楚多了
 if (wl && wl.length) {

     for (i = 0, l = wl.length; i < l; ++i) {
         p = wl[i];
         type = Y.Lang.type(r[p]);

         if (s.hasOwnProperty(p)) {
             // 處理merge邏輯
             if (merge && type == 'object') {
                 Y.mix(r[p], s[p]);
             } else if (ov || !(p in r)) {
                 r[p] = s[p];
             }
         }
     }
 }

 

三、使用Function進行類的定義,不推薦繼承,如需繼承採用成熟的類庫實現繼承

// 類的實現
 function Person(name) {
     this.name = name;
 }

 Person.prototype.sayName = function() {
     alert(this.name);
 };

 var me = new Person("Nicholas");


 // 將this放到局部變量self
 function Persion(name, sex) {
     var self = this;

     self.name = name;
     self.sex = sex;
 }

 

四、使用局部變量緩存反覆查找的對象(包括但不限於全局變量、dom查詢結果、做用域鏈較深的對象)

// 緩存對象
var getComment = function() {
    var dom = $("#common-container"),               // 緩存dom
                appendTo = $.appendTo,                      // 緩存全局變量
        data = this.json.data;                      // 緩存做用域鏈較深的對象
}


//當須要緩存this時必須使用self變量進行緩存
// 緩存this
function Row(name) {
    var self = this;

    self.name = name;
    $(".row").click(function() {
        self.getName();
    });
}

 

五、不使用eval,採起$.parseJSON

三個緣由:

  • 有注入風險,尤爲是ajax返回數據
  • 不方便debug
  • 效率低,eval是一個執行效率很低的函數

 

8、不規範寫法

一、句尾沒有分號

var isHotel = json.type == "hotel" ? true : false

 

二、變量命名各類各樣

var is_hotel;
var isHotel;
var ishotel;

 

三、if 縮寫

if (isHotel)
    console.log(true)
else
    console.log(false)

 

四、使用 eval

var json = eval(jsonText);

 

五、變量未定義處處都是

function() {
    var isHotel = 'true';
    .......

    var html = isHotel ? '<p>hotel</p>' : "";
}

 

六、超長函數

function() {
    var isHotel = 'true';
    //....... 此處省略500行
    return false;
}

 

 

9、須要注意的地方

  1. window.onload只能使用一次,使用屢次會被最後的覆蓋。

    解決方案:

    • 只引用一次window.onload
    • 使用jQuery的$(docuemnt.ready(function(){}); 可屢次使用
    • 使用函數封裝,代碼地址
  2. CSS放在頁頭引入,javascript放在頁尾引入

  3. 在上線以前,要編譯壓縮代碼
  4. 減小重排與重繪

 

 

 

隨筆整理自 
  https://www.xuanfengge.com/fedoc/
感謝博主分享!
相關文章
相關標籤/搜索