JavaScript語言編程規(guī)范(ES5)

代碼風(fēng)格

命名

1. 為方法、變量取一個好名字, 使代碼易于理解

2. 文件中的私有屬性和方法名應(yīng)該以“__“開頭

3. 常量定義全部大寫, 并用下劃線分隔單詞

4. 方法的命名, 用動詞和動賓結(jié)構(gòu), 并采用首字母小寫的駝峰命名法。

說明:
        get + 非布爾屬性名()
         is + 布爾屬性名()
          set + 屬性名()
          has + 名詞/形容詞()
          動詞()
          動詞 + 賓語()

5. 為保證可讀性, 方法名不宜過長

6. 函數(shù)名、屬性名遵循駝峰命名風(fēng)格

7. 為全局屬性、函數(shù)使用命名空間

8. 不要采用保留字作為鍵值或變量名, 如果確實需要, 請用保留字的同義詞

9. jQuery類型的變量以$開頭

注釋

  • 盡量讓代碼來解釋自己
  • 注釋應(yīng)解釋代碼的意圖, 而不是描述代碼怎么實現(xiàn)的
  • 保證注釋與代碼一致, 避免產(chǎn)生誤導(dǎo)
  • 注釋應(yīng)與其描述代碼位置相鄰, 放在所注釋代碼的上方或右方, 并與代碼采用同樣的縮進
  • 注釋和上面的代碼塊要有空行, 注釋的//和注釋內(nèi)容要有一個空格
  • 不要用注釋保留廢棄的代碼
  • 不要用注釋記錄修改日志
  • 一般單行用// 塊用 /* */ 文檔注釋用/** */

排版

1. 團隊?wèi)?yīng)使用一致的排版風(fēng)格

2. 將排版風(fēng)格固化到IDE的代碼格式化配置文件中, 并讓整個團隊使用

3. 在不同概念之間 , 增加空行

4. 將邏輯緊密相關(guān)的代碼放在一起

5. 控制一行的寬度, 不要超過120個字符

6. 在不同的概念間(關(guān)鍵字, 變量, 操作符)增加空格, 以便清楚區(qū)分概念。

7. 統(tǒng)一采用4空格縮進

8. 數(shù)組和對象初始化, 如果初始值不是很長, 就保持寫在單行上。

9. 給if, for, do, while, switch等語句的執(zhí)行體加大括號{}

10. 控制文件的長度, 最好不要超過500行

11. 如果參數(shù)中有匿名函數(shù), 函數(shù)體從調(diào)用該函數(shù)的左邊開始縮進4個空格, 而不是從function這個關(guān)鍵字開始, 這讓匿名函數(shù)更加易讀

12. 二元和三元操作符始終跟隨著前行, 如果一行實在放不下, 按上述的縮進風(fēng)格進行換行

13. 字符串優(yōu)先使用單引號

14. 使用方法鏈時進行縮進, 同時使用前面加點, 強調(diào)這是方法調(diào)用而不是語句, 如:

$(".item")
              .find("tr")
              .end()
              .find(".open");

15. 花括號和語句在同一行。

16. 花括號前加一個空格

17. 在控制語句(if, while等)的括號前放一個空格, 在函數(shù)調(diào)用及聲明中, 不在函數(shù)的參數(shù)列表前加空格。

方法

1. 方法設(shè)計的第一原則是要短小

2. 方法設(shè)計要遵循單一職責(zé)原則(SRP), 一個方法僅完成一個功能

3. 方法設(shè)計應(yīng)遵循單一抽象層次原則(SLAP)

SLAP原則, 是指一個方法中所有的操作處于相同的操作層, 否則, 跳躍的代碼的抽象層次破壞了代碼的流暢性。

4. 不要把方法的入?yún)?dāng)做工作變量/臨時變量, 除非特別需要

說明:

  1. 每個變量/參數(shù)都有自己獨特的功能, 讓一個變量承擔(dān)多個職責(zé), 變量名無法清晰表達其功能, 會使程序無法理解。
  2. 如果參數(shù)是傳引用方式的, 則方法內(nèi)對參數(shù)的修改, 會傳遞到方法外, 造成意外的錯誤, 如傳引用時, 不想方法內(nèi)修改入?yún)⒌模?建議在參數(shù)前加final關(guān)鍵字。

5. 方法的參數(shù)個數(shù)不宜過多

如果參數(shù)超過了7個, 則維護的難度很大, 建議減少參數(shù)個數(shù)。 如果多個參數(shù)同時多次出現(xiàn)在多個方法中, 說明這些參數(shù)緊密相關(guān), 可以將它們封裝到一個對象中。

語言特性

1. 定義類時, 盡量在原型下定義方法, 在構(gòu)造函數(shù)內(nèi)定義屬性, 從而最大程度發(fā)揮JavaScript引擎優(yōu)化機制

說明: 原型可以降低內(nèi)在占用, 提高運行效率。

2. 向數(shù)組添加元素時, 使用Array.push替代直接賦值

3. 有替代方案時, 禁用使用eval方法

說明:

  1. eval接受一個參數(shù)content, 如果content不是字符串, 則直接返回content, 否則執(zhí)行content語句, 如果content語句執(zhí)行結(jié)果是一個值, 則返回此值, 否則,返回undefined, 這讓程序比較混亂, 導(dǎo)致可讀性差。
  2. 當(dāng)eval()里面包含用戶輸入的話, 存在安全風(fēng)險, 可以用其它更佳、更清晰、更安全的方式來寫代碼。

4. 禁止使用with(){}

使用with讓你的代碼在語義上變得不清晰, 因為with的對象可能與局部變量產(chǎn)生沖突, 從而改變你程序原本的用義。

5. 僅在對象構(gòu)造器、方法和閉包中使用this

  1. 在JavaScript里面, this指針代表的是執(zhí)行當(dāng)前代碼對象的所有者, this語義很特別:
    • 全局對象(大多數(shù)情況下)
    • 調(diào)用者的作用域(使用eval時)
    • DOM樹中的節(jié)點(添加事件處理函數(shù)時)
    • 新創(chuàng)建的對象(在構(gòu)造器時)
    • 其他對象(如果函數(shù)被call()或apply())
  2. 使用this時很容易出錯, 所有只有在下面兩種情況下使用:
    • 在構(gòu)造器中
    • 對象的方法(包括創(chuàng)建的閉包)中

6. 塊內(nèi)函數(shù)必須使用函數(shù)表達式聲明, 塊內(nèi)變量不能與函數(shù)內(nèi)的其他變量同名

7. 使用JSON.parse方法來分析JSON字符串

8. 每句代碼后必須加分號(;)

9. 使用JavaScript字面量而不是封裝基本類

10. 禁止修改內(nèi)置對象的原型

11. JavaScript與HTML分離

12. 聲明變量必須加var關(guān)鍵字

13. 在函數(shù)內(nèi)部使用”use strict"

說明:

  • 消除JavaScript語法的一些不合理、不嚴(yán)謹(jǐn)之處, 減少一些怪異行為
  • 消除代碼運行的一些不安全之處, 保證代碼運行的安全
  • 提高編譯器效率, 提高運行速度
  • 為未來新版本的JavaScript做好鋪墊

在開啟“use strict"后, 以下情況在運行腳本前會拋出SyntaError異常

  • 八進制語法: var n = 023var s = \047
  • with語句
  • 使用delete刪除一個變量名或函數(shù)(不是屬性名)
  • 使用eval或arguments作為變量名或函數(shù)名
  • 使用未來保留字
  • 在語句塊使用函數(shù)聲明, 如if(a>b){function f(){}}
  • 對象字面量中使用相同的屬性名
  • 函數(shù)形參中使用多個相同的參數(shù)名

14. 訪問外部對象或外部對象屬性時, 必須先判斷是否為空

15. 判斷相等時, 使用===!==

16. 使用for/in循環(huán)必須結(jié)合實際具體應(yīng)用場景, 正確使用hasOwnProperty方法

說明:

  • for/in主要用于遍歷對象的屬性, 但不包括對象的內(nèi)置成員(如toString, valueOf)
  • 如果重寫了Object的內(nèi)置屬性, 使用for/in遍歷在不同瀏覽器上的結(jié)果是不同的
  • 如果往原生對象上增加方法或?qū)傩裕?會被遍歷出來, 如果不是業(yè)務(wù)需要遍歷property內(nèi)的屬性, 都要使用hasOwnProperty方法來提高代碼的健壯性
  • 遍歷數(shù)組禁止使用for/in做遍歷, 請用普通的for循環(huán)來做遍歷。

17. 盡量避免給數(shù)組添加屬性

18. 推薦使用簡寫的條件表達式

19. 不要寫復(fù)雜的表達式

20. 采用括號明確計算的優(yōu)先級

21. 在switch語句的每一個case和default中都放置一條break語句。

22. var聲明會被提升至該作用域頂部, 所以聲明變量應(yīng)該寫在作用域頂部(因為即使var聲明不在頂部, 其實也會默認(rèn)提升到作用域頂部, 所以顯式地寫在頂部可讀性更強).

性能編程規(guī)范

1. 緩存jQuery查詢結(jié)果

使用JavaScript訪問DOM元素是比較慢的, 所以使用選擇器的次數(shù)應(yīng)該越少越好, 并且盡可能緩存選中的結(jié)果, 便于后續(xù)反復(fù)使用

2. 避免使用所有元素選擇器$("*")

3. 優(yōu)先使用ID選擇器, 盡量給選擇器指定上下文context

jQuery選擇器性能最佳到最差如下:

  • id選擇器
  • 元素選擇器
  • 類選擇器
  • 屬性選擇器
  • 偽類選擇器

4. 循環(huán)中減少DOM操作

5. 利用事件代理(冒泡)機制

每個JavaScript事件(如click)都會冒泡到父級節(jié)點, 當(dāng)需要給多個元素調(diào)用同一個函數(shù)時, 這點很有用.

6. 盡量不要使用同步的ajax

同步的ajax請求會阻塞界面的渲染, 讓界面產(chǎn)生卡頓情況

內(nèi)存編程規(guī)范

1. 在滿足業(yè)務(wù)特性需求的情況下, 減少DOM對象的動態(tài)創(chuàng)建和刪除.

2. 禁止在循環(huán)、事件操作回調(diào)中使用文本+變量拼接的方式使用jQuery創(chuàng)建DOM。

說明:
jQuery在內(nèi)部實現(xiàn)中為了提高頻繁的DOM創(chuàng)建的性能, 會使用DocumentFragment緩存用戶創(chuàng)建的DOM, 在重復(fù)創(chuàng)建的過程中使用緩存的DOM對象clone創(chuàng)建DOM, 從而提高DOM創(chuàng)建的效率。 但是, 這一優(yōu)化, 僅適用于用戶頻繁創(chuàng)建的DOM內(nèi)容沒有變化的情況, 對于內(nèi)容不斷變化的話, 在頁面沒有卸載的情況下長時間運行

例如(不好)

$("#btn").on("click", function(e){
  var ele = $("#hostelement");
  var content = getValue();
  var $span = $("<span>" + content + "</span>")
  ele.append($span);
});

該方式下, jQuery不會生成DocumentFragment對象, 也不會緩存DOM對象在其內(nèi)部的變量中, 因此重復(fù)、頻繁使用時不會造成DOM泄露產(chǎn)生的問題內(nèi)存上漲。

3. 盡量不要使用iframe

說明:
iframe適用于第三方集成, 文件異步上傳等業(yè)務(wù), 非此類業(yè)務(wù)時, 建議使用HTML方式構(gòu)建, 而不要使用iframe, iframe在加載性能和反復(fù)刪除情況下的內(nèi)存回收都不太理想, 尤其是低版本的瀏覽器。

事件監(jiān)聽

1. 正確使用DOM Event Level 2/3 標(biāo)準(zhǔn)進行事件的綁定和注銷。

2. 頁面卸載、動態(tài)刪除的DOM對象時要注銷綁定的事件監(jiān)聽。

說明:
通常事件監(jiān)聽都是與DOM對象掛鉤的, 當(dāng)事件監(jiān)聽沒有被注銷時, 可能會造成JavaScript對象與DOM對象之間存在引用關(guān)系, 尤其在大量使用閉包的情況下, 容易造成JavaScript對象和DOM的循環(huán)引用。 在IE、firefox上會造成內(nèi)存泄露, 原因是由于IE和firefox都使用引用計數(shù)方式的垃圾回收算法。

var $btn = $(".btn");
$btn.off();
$btn.remove();

3. 不要在HTML標(biāo)簽上嵌入JavaScript事件回調(diào)代碼

說明:
直接將JavaScript字符串作為DOM的事件處理邏輯, 容易引發(fā)IE8版本下無法釋放內(nèi)存的問題。

其它

1. 頁面局部刷新調(diào)整時, 要注銷相應(yīng)的定時器和延時器。

說明:
定時器和延時器容易造成JavaScript對DOM的引用, 在JavaScript對象本身沒有被釋放的情況下, 容易引起DOM對象的泄露。

在局部頁面刷新時, 必須清理相應(yīng)的定時器, 否則會造成多個定時器同時執(zhí)行的業(yè)務(wù)問題和每個定時器對應(yīng)閉包所引用的內(nèi)存無法釋放的問題。

2. 不要在JavaScript代碼中使用console.log輸出。

說明:
console.log輸出會導(dǎo)致瀏覽器內(nèi)存上漲。 在IE下, 只要打開F12, console就會被激活, 后面即使關(guān)閉F12工具也無法關(guān)閉掉console, 內(nèi)存依然占用。

3. 使用完數(shù)組要將數(shù)組的長度置空

說明:
JavaScript是通過引用傳參, 需要在接口中或模塊中明確數(shù)組對象的生命周期責(zé)任, 否則可能會造成一處已經(jīng)置null, 而別處仍然持有引用, 導(dǎo)致內(nèi)存沒有釋放。

?著作權(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)容

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