JS學(xué)習(xí)22(最佳實踐)

可維護(hù)性

JS從完成小的網(wǎng)頁特效和驗證到現(xiàn)在要處理各種復(fù)雜的邏輯,頁面中代碼的數(shù)量也是成倍的增長。這就讓編寫可維護(hù)的代碼變得越來越重要了。

可維護(hù)代碼的特點

可理解性
直觀性
可適應(yīng)性
可拓展性
可調(diào)試性

代碼約定

注釋和縮進(jìn)。
變量命名以名詞開始,函數(shù)名命名以動詞開始,返回布爾值的函數(shù)以is開頭。

松散耦合

不同語言間的緊耦合
CSS,JS,HTML他們天生就需要交互。有時我們不得不在一個里面修改另一個,這就造成了緊耦合,出了錯調(diào)試起來非常麻煩。盡量做到分開。

  • HTML里不要有JS這個比較好做到。
  • JS中有時需要動態(tài)添加HTML, 這個盡量交給JSP,PHP等頁面來做,最后用JS加進(jìn)去就好。
  • 盡量不要在HTML中寫CSS
  • JS中修改樣式最好使用類的方式,這樣所有樣式問題都可以追溯到CSS文件中。

事件處理和應(yīng)用邏輯間的緊耦合
如果將應(yīng)用邏輯直接寫在事件處理函數(shù)中,不管是調(diào)試還是重用都會很不方便,將應(yīng)用邏輯提出來,在事件處理中調(diào)用會是一個比較好的方法。有這么幾個原則:

  • 不要將event對象傳給其他方法,只傳來自event對象中所需的數(shù)據(jù)
  • 任何應(yīng)用邏輯層面的操作都應(yīng)該可以在不執(zhí)行任何事件處理程序的情況下執(zhí)行
  • 任何事件處理程序都應(yīng)該處理事件,然后將時間轉(zhuǎn)交給應(yīng)用邏輯

編程實踐

尊重對象所有權(quán)
在其他語言中,在沒有源碼的時候,類和對象一般是不可變的,就算可以也是添加屬性和方法,不可能覆蓋已有的。但是在JS中,一切都可以修改,覆蓋,重寫,想干啥干啥。這有時就會造成很嚴(yán)重的問題。
尊重對象的所有權(quán)就是說不是屬于你的對象不要隨便修改,即便你覺得這樣會很方便。擁有對象的意思是,這些對象由你創(chuàng)建,由你維護(hù)。像Array,document這些對象顯然不是你的,就不要嘗試修改他們。
避免全局變量

var name = "Nicholas";
function sayName(){
    alert(name);
}

在這里創(chuàng)建了兩個全局變量name和sayName。
這樣看起來沒什么,但是是有問題的,比如變量name覆蓋了window的name屬性,其他需要這個屬性的功能就會因此獲得錯誤的信息。

var MyApplication = {     
    name: "Nicholas",     
    sayName: function(){         
        alert(this.name);     
    } 
}; 
MyApplication.sayName();

這樣大家都使用一個全局變量把自己封裝起來,使用和共存和調(diào)試都很方便:

var Exia = {};
Exia.ProJS = {};
Exia.ProJS.EventUtil = {};
Exia.ProJS.CookieUtil = {};

避免與null進(jìn)行比較
比如:

function sortArray(values){
    if (values != null){
        values.sort(comparator);
    }
}

function sortArray(values){  
    if (values instanceof Array){       
        values.sort(comparator); 
    } 
} 

這時明顯是應(yīng)該使用下面這種判斷更加合理。大多數(shù)情況也應(yīng)該這樣判斷。如果是引用類型就使用instanceof,基本類型就使用typeof。
使用常量
比如URL,設(shè)置的量之類的,放到一個常量里,以后要修改就只需要改一次就好。

var Constants = {
    INVALID_VALUE_MSG: "Invalid value!",     
    INVALID_VALUE_URL: "/errors/invalid.php"
};

重復(fù)值
用戶界面字符串
URLs
任意可能會更改的值
以上這些值提出來會比較方便

性能

曾經(jīng)JS是一種解釋型語言,執(zhí)行速度比編譯型語言慢的多,Chrome率先實現(xiàn)了將JS編為本地機(jī)器碼執(zhí)行的瀏覽器。后來主流的瀏覽器都這么做了。即便是這樣,我們還是要避免寫出低效率的代碼。

注意作用域

隨著作用域鏈中作用域的增加,訪問當(dāng)前作用域以外的變量所花的時間也越多,越遠(yuǎn)越耗時。
避免全局查找
當(dāng)訪問全局變量時就是最慢的,如果在一個局部環(huán)境中要多次訪問全局的變量,先用一個局部變量把它保存起來比較好。

function updateUI(){     
    var doc = document;     
    var imgs = doc.getElementsByTagName("img");     
    for (var i=0, len=imgs.length; i < len; i++){      
        imgs[i].title = doc.title + " image " + i;  
    }
    var msg = doc.getElementById("mydiv");    
    msg.innerHTML = "Update complete.";
}

避免with語句
with起初的目的是為了讓開發(fā)人員少寫點字

function updateBody(){
    alert(document.body.tagName);
    document.body.innerHTML = "Hello world!";
}
function updateBody(){
    with(document.body){
        alert(tagName);
        innerHTML = "Hello world!";
    }
}
function updateBody(){    
    var body = document.body;   
    alert(body.tagName);   
    body.innerHTML = "Hello world!";
}

雖然確實方便了,不過這樣會增加作用域鏈的長度,會更慢,使用新添加局部變量的辦法一般可以達(dá)到目的。

選擇正確方法

和其他語言一樣,性能問題的一部分是和用于解決問題的算法或方法有關(guān)的。
避免不必要的屬性查找
對于變量和數(shù)組中元素的訪問都是O(1)級別的操作,但是要訪問對象屬性的操作則是O(n)級別的。
一旦要多次用到同一個對象的同一個屬性就建議把它保存起來,這樣第一次是O(n),以后的就是O(1)了。
優(yōu)化循環(huán)
減值迭代,從最大值開始減到0,這樣的循環(huán)條件一般都會比增值迭代要高效。因為每次循環(huán)和終止條件對比時減值對比都是和常量0進(jìn)行對比,而增量都是和一個變量甚至是一個對象的屬性做對比,這樣每次循環(huán)累計起來就會有一定的差距了。
簡化終止條件,每次循環(huán)都會和終止條件對比,如果你的終止條件直接是一個對象的一個屬性,那每次都要進(jìn)行O(n)的查找。
簡化循環(huán)體,這個不用說啥了。
展開循環(huán)
當(dāng)循環(huán)次數(shù)確定時,使用多次函數(shù)調(diào)用而不是循環(huán)會更快。
不過一般循環(huán)的次數(shù)都是不確定的呢,
在處理大數(shù)據(jù)集時,可以使用一個叫Duff裝置的技術(shù)。這個技術(shù)將循環(huán)拆成每8次一組。在處理大量數(shù)據(jù)時提升效果顯著。畢竟每8次才有一次處理循環(huán)的開銷。當(dāng)然數(shù)據(jù)量小的時候就并不劃算了。

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);

其他提升性能的方法
原生方法較快
Switch語句較快
位運算符較快

最小化語句數(shù)

簡單來講,就是完成多個操作的單個語句要比完成單個操作的多個語句快。
多個變量聲明

var count = 5,      
    color = "blue",    
    values = [1,2,3],  
    now = new Date(); 

使用數(shù)組和對象字面量

優(yōu)化DOM交互

最小化現(xiàn)場更新
一旦你需要訪問的DOM部分是已經(jīng)顯示頁面的一部分,那么你就是在進(jìn)行一次現(xiàn)場更新。每次現(xiàn)場更新都有一個很大的性能懲罰,瀏覽器要重新計算各種尺寸和屬性。所以更新次數(shù)要盡可能少,動作要盡可能的小。
比如你要給一個ul添加多個li,那把所有l(wèi)i準(zhǔn)備好一起塞到ul里就比一個一個塞要好。
使用innerHTML
用innerHTML來創(chuàng)建DOM節(jié)點,不僅寫起來舒服,執(zhí)行起來也快。這個同樣,把字符串拼好了再一次性加到頁面里,這樣才高效。
使用事件代理
就是在整個文檔上添加事件,文檔中各個事件冒泡到文檔上統(tǒng)一處理。
注意HTMLCollection
任何時候訪問這種類型的變量都是在文檔上進(jìn)行了一次查詢,這是個很昂貴的操作。尤其是在循環(huán)中。。。

var images = document.getElementsByTagName("img"),    
    image,  
    i,
    len;
for (i=0, len=images.length; i < len; i++){  
    image = images[i];     
    //其他操作
} 

這里既在循環(huán)終止條件中避免了對HTMLCollection的多次訪問,又在循環(huán)體里使用image儲存了當(dāng)前要使用的元素,從而避免了多次訪問HTMLCollection

部署

構(gòu)建過程

我們開發(fā)Web應(yīng)用時JS文件是按照可維護(hù)性優(yōu)先的原則組織的,但是這樣會存在一些問題:

  • 把帶有自己注釋的代碼放上去,別人就更容易知道你的意圖,有可能被人找到漏洞
  • 書寫代碼時我們保證代碼簡單易讀,但是對于性能是不利的。瀏覽器并不能從空格和各式各樣的變量中獲得什么有用的信息

所以使用構(gòu)建工具將多個JS合并壓縮就很必要了。這樣的工具有很多,挑順手的用。

驗證

JSLint可以在線驗證JS代碼中的潛在語法錯誤。
在開發(fā)周期中添加這個環(huán)節(jié)可以作為發(fā)現(xiàn)代碼潛在問題的辦法。
把驗證添加到構(gòu)建過程中是很常用且推薦的做法。

壓縮

文件壓縮
如果每次都把帶有各種空格和注視的JS通過網(wǎng)絡(luò)傳送到瀏覽器,顯然有太多不必要的開銷。
在部署前使用壓縮工具壓縮JS文件也是必要的。
HTTP壓縮
對于服務(wù)器向瀏覽器傳送文件這個過程,也是可以優(yōu)化的,服務(wù)器和瀏覽器現(xiàn)在都有壓縮和解壓縮功能。

最后編輯于
?著作權(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)容

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,496評論 6 13
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,276評論 25 708
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,806評論 18 399
  • 九月的上海依然有些悶熱,我坐在地鐵車廂發(fā)著呆。 每天我們都與形形色色的人擦身而過,也許有過眼神交流,也許有過一面之...
    戀粉破曉閱讀 322評論 2 3
  • 生活總是在不經(jīng)意間感動你,有時再微小的事物也能戳中自己的淚點…… 感謝生命中的每一天,和出現(xiàn)在生命里的每個人及其每...
    井溢閱讀 184評論 0 0

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