摘要:大多數(shù)情況下,可以是同局部變量完成相同的事情而不引入新的作用域。選擇正確的方法避免不必要的屬性查找一旦多次用到屬性對象,應該將其存儲在局部變量中。盡可能多的使用局部變量將屬性查找替換為值查找。
1、可維護性 1.1 可維護代碼特征
1. 可理解性
2. 直觀性
3. 可適應性
4. 可擴展性
5. 可調(diào)試性
1、可讀性(代碼縮進和代碼注釋)
2、變量和函數(shù)命名
變量名應該為名詞
函數(shù)名應該以動詞開始
變量和函數(shù)都應使用合乎邏輯的名字,不要擔心長度。
3、變量類型透明
(1)第一種方式是初始化,初始化為一個特定的數(shù)據(jù)類型可以很好的指明變量的類型;
//通過初始化指定變量類型 var found = false; //布爾型 var count = -1; //數(shù)字 var name = ""; //字符串 var person = null; //對象
缺點在于無法用于函數(shù)聲明中的函數(shù)參數(shù)。
(2)第二種方式是使用匈牙利標記法來指定變量的類型。匈牙利標記法在變量名之前加上一個或多個字符來表示數(shù)據(jù)類型。
//用于指定數(shù)據(jù)類型的匈牙利標記法 var bFound = false; //布爾型 var iCount = -1; //數(shù)字 var sName = ""; //字符串 var oPerson = null; //對象
缺點在于讓代碼某種程度上難以閱讀,阻礙了沒有用它時代碼的直觀性和句子式的特征。
(3)第三種方式是使用類型注釋。
//用于指定類型的類型注釋 var found /*:Boolean*/ = false; var count /*:int*/ = -1; var name /*:String*/ = ""; var person /*:Object*/ = null;
缺點在于不能用多行注釋一次注釋大塊的代碼。(在每一行上使用單行注釋可解決這個問題)
1.3 松散耦合只要應用的某個部分過于依賴另一部分,代碼就是耦合過緊,難以維護。
1、解耦HTML/JavaScript
2、解耦CSS/JavaScript
由于JavaScript必須與HTML和CSS共存,所以讓各自完全定義起自己的目的非常重要:
JavaScript應該定義行為,HTML應該定義內(nèi)容,CSS應該定義外觀。
3、解耦應用邏輯/事件處理程序
應用和業(yè)務邏輯之間松散耦合的幾條原則:
勿將event對象傳給其他方法;只傳來自event對象中所需的數(shù)據(jù);
任何可以在應用層面的動作都應該可以在不執(zhí)行任何事件處理程序的情況下進行;
任何事件處理程序都應該處理事件,然后將處理轉(zhuǎn)交給應用邏輯。
1.4 編程實踐1、尊重對象所有權(quán)
不要為實例或原型添加屬性;
不要為實例或原型添加方法;
不要重定義已存在的方法;
可以通過以下方式為對象創(chuàng)建新的功能
創(chuàng)建包含所需功能的新對象,并用它與相關對象進行交互;
創(chuàng)建自定義類型,繼承需要進行修改的類型,然后可以為自定義類型添加額外功能;
2、避免全局量
最多創(chuàng)建一個全局變量,讓其他對象和函數(shù)存在其中。
var MyApplication = { name : "Nicholas", sayName : function(){ alert(this.name); } };
命名空間包括創(chuàng)建一個用于放置功能的對象。唯一的全局變量作為一個容器,其中定義了其他方法,用這種方式將功能組合在一起的對象,叫做命名空間。命名空間有助于確保代碼可以在同一頁面上與其他代碼以無害的方式一起工作。
3、避免與null進行比較
直接將值與null比較是使用過度的,并且常常由于不充分的類型檢查導致錯誤。如果看到了與null比較的代碼,嘗試使用一下技術替換:
如果值應為一個引用類型,使用instanceof操作符檢查其構(gòu)造函數(shù);
如果值應為一個基本類型,使用typeof檢查其類型;
如果是希望對象包含某個特定的方法名,則使用typeof操作符確保指定名字的方法存在于對象上。
4、使用常量
將數(shù)據(jù)從應用邏輯分離出來的思想。可以在不冒引入錯誤的風險的同時,就改變數(shù)據(jù)。如下例
function validate(value) { if(!value) { alert("Invalid value"); location.href = "/errors(invalid.php)"; } }
可以通過將數(shù)據(jù)抽取出來變成多帶帶定義的常量的方式,將應用邏輯與數(shù)據(jù)修改隔離開來。修改如下:
var Constants = { INVALID_VALUE_MSG: "Invalid value", INVALID_VALUE_URL: "/errors/invalid.php" }; function validate(value) { if(!value) { alert(Constant.INVALID_VALUE_MSG); location.href = COnstant.INVALID_VALUE_URL; } }
關鍵在于將數(shù)據(jù)和使用它的邏輯進行分離。需要提取作為常量的值大致有以下幾種情況:
重復值:任何在多處用到的值都應抽取為一個常量;
用戶界面字符串:任何用于顯示給用戶的字符串,都應該被抽取出來以方便國際化;
URLs:在WEB應用中,資源位置很容易變更,所以推薦用一個公共地方存放所有的URL;
任意可能會更改的值
2、性能 2.1 注意作用域訪問全局變量總是比訪問局部變量慢。只要能減少花費在作用域上的時間,就能增加腳本的整體性能。
1、避免全局查找
function updateUI() { var imgs = document.getElementsByTagName("img"); for(var i=0, len=imgs.length; i上述函數(shù)看起來完全正常,但是它包含了三個對于全局document對象的引用。通過創(chuàng)建一個指向document對象的局部變量,就可以通過限制一次全局查找來改進這個函數(shù)的性能。改進后的代碼如下:
function updateUI() { var doc = document; var imgs = doc.getElementsByTagName("img"); for(var i=0, len=imgs.length; i2、避免with語句
with語句會創(chuàng)建自己的作用域,因此會增加其中執(zhí)行的代碼的作用域的長度。
大多數(shù)情況下,可以是同局部變量完成相同的事情而不引入新的作用域。function updateBody() { with(document.body) { alert(tagName); innerHTML = "Hello World!"; } }以上代碼中的with語句讓document.body變得更容易使用,但是其實可以使用局部變量達到相同的效果。
function updateBody() { var body = document.body; alert(body.tagName); body.innerHTML = "Hello World!"; }2.2 選擇正確的方法1、避免不必要的屬性查找
一旦多次用到屬性對象,應該將其存儲在局部變量中。一般來講,只要能減少算法的復雜度,就要盡可能減少。盡可能多的使用局部變量將屬性查找替換為值查找。進一步講,如果既可以用數(shù)字化的數(shù)組位置進行訪問,也可以使用命名屬性,那么使用數(shù)字位置。
2、優(yōu)化循環(huán)
(1)減值迭代:很多情況下,從最大值開始,在循環(huán)中不斷減值的迭代器更加高效。
(2)簡化終止條件
(3)簡化循環(huán)體:確保沒有某些可以被很容易移出循環(huán)的密集操作。
(4)使用后測循環(huán):最常使用的for循環(huán)和while循環(huán)都是前測試循環(huán)。而如do-while這種后測試循環(huán),可以避免最終終止條件的計算,因此運行更快。
3、展開循環(huán)(可以考慮一種叫做Duff裝置的技術)
當循環(huán)次數(shù)是確定的,消除循環(huán)并使用多次函數(shù)調(diào)用往往更快。如下循環(huán)代碼for(var i=0; i可以改為
process(values[0]); process(values[1]); process(values[2]);//Duff裝置的基本概念是通過計算迭代的次數(shù)是否為8的倍數(shù)將一個循環(huán)展開為一系列語句。
var iterations = Math.ceil(values.length / 8); var startAt = values.length % 8; var i = 0; do{ switch(startAt) { case 0: process(value[i++]); case 7: process(value[i++]); case 6: process(value[i++]); case 5: process(value[i++]); case 4: process(value[i++]); case 3: process(value[i++]); case 2: process(value[i++]); case 1: process(value[i++]); } startAt = 0; }while(--iterations > 0);Math.ceil()函數(shù)返回大于或等于一個給定數(shù)字的最小整數(shù)
Math.floor()函數(shù)返回小于或等于一個給定數(shù)字的最大整數(shù)DUff裝置的實現(xiàn)是通過將values數(shù)組中的元素個數(shù)除以8來計算出循環(huán)需要進行多少次迭代的。然后使用取整的上限函數(shù)確保結(jié)果是整數(shù)。如果完全根據(jù)8來進行迭代,可能會有一些不能被處理到的元素,這個數(shù)量保存在startAt變量中。首次執(zhí)行該循環(huán)時,會檢查startAt變量看有需要多少次額外調(diào)用。那么最開始的時候process()則只會被調(diào)用2次。在接下來的循環(huán)中,startAt被重置為0,這樣之后的每次循環(huán)都會調(diào)用8次process()。展開循環(huán)可以提升大數(shù)據(jù)及的處理速度。
4、避免雙重解釋
//某些代碼求值——避免!! eval("alert("Hello World!")"); //創(chuàng)建新函數(shù)——避免!! var sayHi = new Function("alert("Hello World!")"); //設置超時——避免!! setTimeout("alert("Hello World!")",500);修改為
//某些代碼求值——已修正 alert("Hello World!"); //創(chuàng)建新函數(shù)——已修正 var sayHi = function(){ alert("Hello World!") }; //設置超時——已修正 setTimeout(function(){ alert("Hello World!"); },500);5、性能其他的注意事項
原生方法比較快;
Switch語句較快;
位運算符比較快
2.3 最小化語句數(shù)完成多個操作的單個語句要比完成單個操作的多個語句快。
1、多個變量的聲明
//4個語句——浪費! var count = 5; var color = "blue"; var values = [1,2,3]; var now = new Date();修改為
var count = 5; color = "blue"; values = [1,2,3]; now = new Date();2、插入迭代值
當使用迭代值(也就是在不同的位置進行增加或者減少的值)的時候,盡可能使用合并語句。
var name = values[i]; i++;例如以上代碼修改為
var name = values[i++];3、使用數(shù)組和對象字面量
創(chuàng)建數(shù)組和對象的方法有兩種:使用構(gòu)造函數(shù)或者是字面量。使用構(gòu)造函數(shù)總是要用到更多的語句來插入元素或者定義屬性,而字面量可以將這些操作在一個語句中完成。
//用4個語句創(chuàng)建和初始化數(shù)組——浪費 var values = new Array(); values[0] = 123; values[1] = 456; values[2] = 789; //只用一條語句創(chuàng)建和初始化數(shù)組 var values = [123, 456, 789];只要有可能,盡量使用數(shù)組和對象的字面量表達方式來消除不必要的語句。
2.4 優(yōu)化DOM交互1、最小化現(xiàn)場更新
之所以叫現(xiàn)場更新,是因為需要立即(現(xiàn)場)對頁面對用戶的顯示進行更新。
一旦需要更新DOM,請考慮使用文檔片段來構(gòu)建DOM結(jié)構(gòu),然后再將其添加到現(xiàn)存的文檔中。
2、使用innerHTML
對于大的DOM更改,使用innerHTML要比使用標準DOM方法創(chuàng)建同樣的DOM結(jié)構(gòu)快得多。
使用innerHTML的關鍵在于最小化調(diào)用它的次數(shù)。
3、使用事件代理
任何可以冒泡的事件都不僅僅可以在事件目標上進行處理,目標的任何祖先節(jié)點上也能處理。使用這個只是就可以將事件處理程序附加到更高層的地方負責多個目標的事件處理。
4、注意HTMLCollection
任何時候要訪問HTMLCollection,不管它是一個屬性還是方法,都是在文檔上進行一個查詢,這個查詢開銷很昂貴。最小化訪問HTMLCollection的次數(shù)可以極大地改進腳本的性能。當在循環(huán)中使用HTMLCollection的時候,下一步應該是獲取要使用的項目的引用,以便避免在循環(huán)體內(nèi)多次調(diào)用HTMLCollection。
var images = document.getElementsByTagName("img"); i, len; for(i=0, length=images.length; i修改為
var images = document.getElementsByTagName("img"); image, i, len; for(i=0, length=images.length; i編寫JavaScript的時候,一定要知道何時返回HTMLCollection對象,這樣你就可以最小化他們的訪問。發(fā)生一下情況時會返回HTMLCollection對象:
進行了對getElementByTagName()的調(diào)用;
獲取了元素的childNodes屬性;
獲取了元素的attribute屬性;
訪問特殊的集合,如document.forms、document.images等。
當使用HTMLCOllection對象時,合理使用會極大提升代碼的執(zhí)行速度。
3、部署1、構(gòu)建過程
2、驗證
3、壓縮為了協(xié)助部署,推薦設置一個可以將JavaScript合并為較少文件的構(gòu)建過程;
有了構(gòu)建過程也可以對源代碼自動運行額外的處理和過濾,例如可以運行JavaScript驗證器來確保沒有語法錯誤或者是代碼沒有潛在的問題;
在部署前推薦使用壓縮器將文件盡可能變小;
和HTTP壓縮一起使用可以讓JavaScript文件盡可能小,因此對整體頁面性能的影響也會最小。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/109253.html
摘要:編程書籍的整理和收集最近一直在學習深度學習和機器學習的東西,發(fā)現(xiàn)深入地去學習就需要不斷的去提高自己算法和高數(shù)的能力然后也找了很多的書和文章,隨著不斷的學習,也整理了下自己的學習筆記準備分享出來給大家后續(xù)的文章和總結(jié)會繼續(xù)分享,先分享一部分的 編程書籍的整理和收集 最近一直在學習deep learning深度學習和機器學習的東西,發(fā)現(xiàn)深入地去學習就需要不斷的去提高自己算法和高數(shù)的能力然后...
摘要:也就是說避免屬性查找或其他的操作。簡化循環(huán)體循環(huán)體是執(zhí)行最多的,所以要確保其被最大限度地優(yōu)化。代碼組織組織代碼要考慮到可維護性并不一定是傳送給瀏覽器的最好方式。 最佳實踐 可維護性 什么是可維護性的代碼 如果說代碼是可維護的,它需要遵循以下特點 可理解性——其他人可以接手代碼并理解它的意圖和一般途徑,而無需原開發(fā)人員的完整解釋。 直觀性——代碼中的東西一看就能明白,不管其操作過程多...
閱讀 4365·2021-11-24 10:24
閱讀 1409·2021-11-22 15:22
閱讀 2038·2021-11-17 09:33
閱讀 2428·2021-09-22 15:29
閱讀 515·2019-08-30 15:55
閱讀 1652·2019-08-29 18:42
閱讀 2731·2019-08-29 12:55
閱讀 1772·2019-08-26 13:55