註釋可以加強代碼的可讀性以及可維護性,固然,理想狀況是滿滿的註釋,但這不太現實。因此咱們只須要在一些關鍵的地方添上註釋:javascript
函數和方法:尤爲是返回值,由於直接看不出來html
大段代碼(功能模塊):說明模塊功能java
複雜算法:寫出關鍵點,方便理解算法
Hack:說明爲了修復什麼問題,當前方案是否完善,可否改進數組
經過初始值來暗示,例如:安全
var found = false; var count = 1; var name = ''; var student = null;
結構層:HTML性能優化
行爲層:JS服務器
表現層:CSSide
儘可能不要「越權」,若是實在是想越權,也應該用文檔或者註釋說明。儘可能不要出現緊耦合,例如:函數
JS-HTML:
elem.innerHTML = '<div class="block"><h2>title</h2><p>content</p></div>'; //最好用下面的方式代替(顯示頁面中的隱藏元素) //elem.style.display = 'block';
JS-CSS:
elem.style.color = '#e0e0e0'; //最好用下面的方式代替(設置類,不要直接設置樣式) //elem.className = 'my_class';
JS-JS:
//邏輯耦合 elem.onclick = function(e){ if(txt.value !== null && txt.value !== '' &&...){ //DOM操做 } } //最好用下面的方式代替(分離邏輯功能塊) function isValid(){ return txt.value !== null && txt.value !== '' &&...; } function display(){ //DOM操做 } elem.onclick = function(e){ if(isValid()){ display(); } }
避免邏輯耦合的幾條原則:
不要傳遞event對象,只傳須要的數據
觸發事件不該該是執行動做的惟一方式
事件處理器應該只處理事件相關數據(獲取事件源,座標值等等),而後把處理轉交給應用邏輯
尊重對象全部權,不要隨便修改別人的對象,具體要求:
不要給實例/原型添加屬性或方法
不要重寫已存在的方法
可選方案:
組合:建立實現了所需功能的新對象,引用須要的對象
繼承:建立自定義類型,繼承須要修改的類型,而後添加額外功能
用命名空間避免全局變量,例如:
var mySystem = {}; mySystem.mod1 = {...};
用常量提升可維護性,例如:
var Consts = {}; Consts.IMG_PATH = '../imgs/';
注意:常量包括經常使用的CSS類名和其它任何可能影響維護的值
把須要屢次引用的全局變量另存爲局部變量
with語句會延長做用域,存在長做用域查找的開銷,能夠用另存局部變量來代替(沒有with方便,但多少能好一點)
儘可能把重複使用的值另存爲局部變量,例如:
//不要用下面的代碼(6次屬性查找) var qs = window.location.href.substring(window.location.href.indexOf('?')); //應該用下面的代碼(4次,並且更具可讀性) var url = window.location.href; var qs = url.substring(url.indexOf('?'));
優化循環
減值迭代更快(i–)
簡化終止條件,每次循環都會檢查終止條件,簡化條件能提升效率
簡化循環體,儘可能減小循環體裏面的計算量
使用後測試循環(do...while),能夠避免第一次循環前的判斷
展開循環
若是循環次數肯定,最好不要用循環,由於循環存在建立循環和處理終止條件的額外開銷,例如:
for(i = 0;i < 2;i++){ process(arr[i]); } //下面的比上面的快 process(arr[0]); process(arr[1]); process(arr[2]);
若是循環次數不能肯定,能夠用Duff技術(Tom Duff發明的)展開一部分循環,提升效率,例如:
//credit: Jeff Greenberg for JS implementation of Duff’s Device //假設 values.length > 0 var iterations = Math.ceil(values.length / 8); var startAt = values.length % 8; var i = 0; do { switch(startAt){ case 0: process(values[i++]); case 7: process(values[i++]); case 6: process(values[i++]); case 5: process(values[i++]); case 4: process(values[i++]); case 3: process(values[i++]); case 2: process(values[i++]); case 1: process(values[i++]); } startAt = 0; } while (--iterations > 0); //以上代碼來自:http://www.cnblogs.com/kylindai/archive/2013/12/04/3458476.html
或者另外一個更快的Duff方法:
//credit: Speed Up Your Site (New Riders, 2003) var iterations = Math.floor(values.length / 8); var leftover = values.length % 8; var i = 0; if (leftover > 0){ do { process(values[i++]); } while (--leftover > 0); } do { process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); process(values[i++]); } while (--iterations > 0); //以上代碼來自:http://www.cnblogs.com/kylindai/archive/2013/12/04/3458476.html
避免雙重解釋
雙重解釋是指:用js解析js。具體是用eval()函數或者new Function(strCode)或者setTimeout(strCode)
雙重解釋的缺點:須要再啓動一個解析器來解析,存在很大的開銷,比直接解析慢不少
原生方法更快
原生方法是用用C/C++編譯好的模塊,因此要快得多
switch比if-else快
緣由很差說,能夠參考CSDN
位運算並無更快
在其它語言中把數學運算簡化爲位運算可以提高計算速度,但js中沒這一說,由於js內部只有一種數值類型(double),因此作位運算須要折騰:double – int – 作位運算 – double,性能可想而知
減小語句數量
用1個var聲明多個變量
插入迭代值,arr[i++]一條語句搞定,不用把i++獨立成一個語句
用數組/對象字面量,代碼行數明顯變少了
DOM優化
減小現場更新,能夠用DocumentFragment優化
用innerHTML建立DOM節點比建立一堆節點再組裝要快,但存在JS-HTML耦合問題,慎重考慮
用事件委託
注意實時更新的集合(NodeList、NamedNodeMap、HTMLCollection)
除了把引用另存爲局部變量外,還要注意訪問其屬性也是須要從新查詢的,好比:var imgs = document.images;訪問imgs.length也須要再查一次
用驗證工具(如JSLint)檢查代碼,發現語法錯誤以外的潛在問題
去掉註釋(出於安全性考慮)
合併js文件,儘可能減小外部文件數量
壓縮代碼(如YUI壓縮器),減小代碼自己大小,也能夠同時混淆代碼,提升安全性,但混淆代碼自己存在風險,可能引起錯誤
開啓服務器壓縮功能,例如gzip模塊