JS運用的幾個小技巧

1.使用 === 代替 ==

JavaScript 使用2種不一樣的等值運算符:===|!== 和 ==|!=,在比較操做中使用前者是最佳實踐。javascript

「若是兩邊的操做數具備相同的類型和值,===返回true,!==返回false。」——《JavaScript:語言精粹》php

然而,當使用==和!=時,你可能會遇到類型不一樣的狀況,這種狀況下,操做數的類型會被強制轉換成同樣的再作比較,這可能不是你想要的結果。html

 

2.Eval=邪惡

起初不太熟悉時,「eval」讓咱們可以訪問JavaScript的編譯器(譯註:這看起來很強大)。從本質上講,咱們能夠將字符串傳遞給eval做爲參數,而執行它。html5

這不只大幅下降腳本的性能(譯註:JIT編譯器沒法預知字符串內容,而沒法預編譯和優化),並且這也會帶來巨大的安全風險,由於這樣付給要執行的文本過高的權限,避而遠之。java

 

3.省略未必省事

從技術上講,你能夠省略大多數花括號和分號。大多數瀏覽器都能正確理解下面的代碼:web

1
2
if (someVariableExists) 
    x = false

而後,若是像下面這樣:chrome

1
2
3
if (someVariableExists) 
    x = false 
    anotherFunctionCall();

有人可能會認爲上面的代碼等價於下面這樣:json

1
2
3
4
if (someVariableExists) { 
    x = false
    anotherFunctionCall(); 
}

不幸的是,這種理解是錯誤的。實際上的意思以下:數組

1
2
3
4
if (someVariableExists) { 
    x = false
anotherFunctionCall();

你可能注意到了,上面的縮進容易給人花括號的假象。無可非議,這是一種可怕的實踐,應不惜一切代價避免。僅有一種狀況下,即只有一行的時候,花括號是能夠省略的,但這點是飽受爭議的。瀏覽器

1
if (2 + 2 === 4) return 'nicely done' ;

未雨綢繆

極可能,有一天你須要在if語句塊中添加更多的語句。這樣的話,你必須重寫這段代碼。底線——省略是雷區。

 

4.使用JSLint

JSLint是由大名鼎鼎的道格拉斯(Douglas Crockford)編寫的調試器。簡單的將你的代碼粘貼進JSLint中,它會迅速找出代碼中明顯的問題和錯誤。

「JSLint掃面輸入的源代碼。若是發現一個問題,它返回一條描述問題和一個代碼中的所在位置的消息。問題並不必定是語法錯誤,儘管一般是這樣。JSLint還會查看一些編碼風格和程序結構問題。這並不能保證你的程序是正確的。它只是提供了另外一雙幫助發現問題的眼睛。」——JSLing 文檔

部署腳本以前,運行JSLint,只是爲了確保你沒有作出任何愚蠢的錯誤。

 

5.將腳本放在頁面的底部

在本系列前面的文章裏已經提到過這個技巧,我粘貼信息在這裏。

 

記住——首要目標是讓頁面儘量快的呈獻給用戶,腳本的夾在是阻塞的,腳本加載並執行完以前,瀏覽器不能繼續渲染下面的內容。所以,用戶將被迫等待更長時間。

若是你的js只是用來加強效果——例如,按鈕的單擊事件——立刻將腳本放在body結束以前。這絕對是最佳實踐。

建議

1
2
3
4
5
<p>And now you know my favorite kinds of corn. < /p
<script type = "text/javascript" src= "path/to/file.js" >< /script
<script type = "text/javascript" src= "path/to/anotherFile.js" >< /script
< /body
< /html >

6.避免在For語句內聲明變量

當執行冗長的for語句時,要保持語句塊的儘可能簡潔,例如:

糟糕

1
2
3
4
5
for (var i = 0; i < someArray.length; i++) { 
    var container = document.getElementById( 'container' ); 
    container.innerHtml += 'my number: ' + i; 
    console.log(i); 
}

注意每次循環都要計算數組的長度,而且每次都要遍歷dom查詢「container」元素——效率嚴重地下!

建議

1
2
3
4
5
var container = document.getElementById( 'container' ); 
for (var i = 0, len = someArray.length; i < len;  i++) { 
    container.innerHtml += 'my number: ' + i; 
    console.log(i); 
}

感興趣能夠思考如何繼續優化上面的代碼,歡迎留下評論你們分享。

 

7.構建字符串的最優方法

當你須要遍歷數組或對象的時候,不要總想着「for」語句,要有創造性,總能找到更好的辦法,例如,像下面這樣。

1
2
var arr = [ 'item 1' , 'item 2' , 'item 3' , ...]; 
var list = '<ul><li>' + arr. join ( '</li><li>' ) + '</li></ul>' ;

 我不是你心中的神,但請你相信我(不信你本身測試)——這是迄今爲止最快的方法!使用原生代碼(如 join()),無論系統內部作了什麼,一般比非原生快不少。——James Padolsey, james.padolsey.com

 

8.減小全局變量

 只要把多個全局變量都整理在一個名稱空間下,擬將顯著下降與其餘應用程序、組件或類庫之間產生糟糕的相互影響的可能性。——Douglas Crockford

1
2
3
4
5
6
var name = 'Jeffrey'
var lastName = 'Way'
 
function doSomething() {...} 
 
console.log(name); // Jeffrey -- 或 window.name

更好的作法

1
2
3
4
5
6
var DudeNameSpace = { 
    name : 'Jeffrey'
    lastName : 'Way'
    doSomething : function () {...} 
console.log(DudeNameSpace.name); // Jeffrey

注:這裏只是簡單命名爲 「DudeNameSpace」,實際當中要取更合理的名字。

 

 9.給代碼添加註釋

彷佛沒有必要,當請相信我,儘可能給你的代碼添加更合理的註釋。當幾個月後,重看你的項目,你可能記不清當初你的思路。或者,假如你的一位同事須要修改你的代碼呢?總而言之,給代碼添加註釋是重要的部分。

1
2
3
4
// 循環數組,輸出每項名字(譯者注:這樣的註釋彷佛有點多餘吧).  
for ( var i = 0, len = array.length; i < len; i++) { 
    console.log(array[i]); 
}

 10.擁抱漸進加強

確保javascript被禁用的狀況下能平穩退化。咱們老是被這樣的想法吸引,「大多數個人訪客已經啓用JavaScript,因此我沒必要擔憂。」然而,這是個很大的誤區。

你可曾花費片刻查看下你漂亮的頁面在javascript被關閉時是什麼樣的嗎?(下載 Web Developer 工具就能很容易作到(譯者注:chrome用戶在應用商店裏自行下載,ie用戶在Internet選項中設置)),這有可能讓你的網站支離破碎。做爲一個經驗法則,設計你的網站時假設JavaScript是被禁用的,而後,在此基礎上,逐步加強你的網站。

 

11.不要給」setInterval」或」setTimeout」傳遞字符串參數

考慮下面的代碼:

1
2
3
setInterval( 
"document.getElementById('container').innerHTML += 'My new number: ' + i" , 3000 
);

不只效率低下,並且這種作法和」eval」一模一樣。從不給setInterval和setTimeout傳遞字符串做爲參數,而是像下面這樣傳遞函數名。

1
setInterval(someFunction, 3000);

12.不要使用」with」語句

乍一看,」with」語句看起來像一個聰明的主意。基本理念是,它能夠爲訪問深度嵌套對象提供縮寫,例如……

1
2
3
4
with (being.person. man .bodyparts) { 
    arms = true
    legs = true
}

而不是像下面這樣:

1
2
being.person. man .bodyparts.arms = true
being.person. man .bodyparts.legs= true ;

不幸的是,通過測試後,發現這時「設置新成員時表現得很是糟糕。做爲代替,您應該使用變量,像下面這樣。

1
2
3
var o = being.person. man .bodyparts; 
o.arms = true
o.legs = true ;

13.使用{}代替 new Ojbect()

在JavaScript中建立對象的方法有多種。多是傳統的方法是使用」new」加構造函數,像下面這樣:

1
2
3
4
5
6
var o = new Object(); 
o.name = 'Jeffrey'
o.lastName = 'Way'
o.someFunction = function () { 
    console.log(this.name); 
}

然而,這種方法的受到的詬病不及實際上多。做爲代替,我建議你使用更健壯的對象字面量方法。

更好的作法

1
2
3
4
5
6
7
var o = { 
    name: 'Jeffrey'
    lastName = 'Way'
    someFunction : function () { 
       console.log(this.name); 
   
};

注意,果你只是想建立一個空對象,{}更好。

1
var o = {};

「對象字面量使咱們可以編寫更具特點的代碼,並且相對簡單的多。不須要直接調用構造函數或維持傳遞給函數的參數的正確順序,等」——dyn-web.com

 

14.使用[]代替 new Array()

這一樣適用於建立一個新的數組。

例如:

1
2
3
var a = new Array(); 
a[0] = "Joe"
a[1] = 'Plumber' ;

更好的作法:

1
var a = [ 'Joe' , 'Plumber' ];

「javascript程序中常見的錯誤是在須要對象的時候使用數組,而須要數組的時候卻使用對象。規則很簡單:當屬性名是連續的整數時,你應該使用數組。不然,請使用對象」——Douglas Crockford

 

15.定義多個變量時,省略var關鍵字,用逗號代替

1
2
3
var someItem = 'some string'
var anotherItem = 'another string'
var oneMoreItem = 'one more string' ;

更好的作法

1
2
3
var someItem = 'some string'
     anotherItem = 'another string'
     oneMoreItem = 'one more string' ;

…應而不言自明。我懷疑這裏真的有所提速,但它能是你的代碼更清晰。

 

16.謹記,不要省略分號

從技術上講,大多數瀏覽器容許你省略分號。

1
2
3
4
var someItem = 'some string' 
function doSomething() { 
   return 'something' 
}

已經說過,這是一個很是糟糕的作法可能會致使更大的,難以發現的問題。

更好的作法

1
2
3
4
var someItem = 'some string'
function doSomething() { 
   return 'something'
}

17.」For in」語句

當遍歷對象的屬性時,你可能會發現還會檢索方法函數。爲了解決這個問題,總在你的代碼裏包裹在一個if語句來過濾信息。

1
2
3
4
5
for (key in object) { 
    if (object.hasOwnProperty(key) { 
       ... then do something... 
   
}

參考 JavaScript:語言精粹,道格拉斯(Douglas Crockford)。

 

18.使用Firebug的」timer」功能優化你的代碼

在尋找一個快速、簡單的方法來肯定操做須要多長時間嗎?使用Firebug的「timer」功能來記錄結果。

1
2
3
4
5
function TimeTracker(){ 
  console. time ( "MyTimer" ); 
  for (x=5000; x > 0; x--){} 
  console.timeEnd( "MyTimer" ); 
}

 

19.自執行函數

和調用一個函數相似,它很簡單的使一個函數在頁面加載或父函數被調用時自動運行。簡單的將你的函數用圓括號包裹起來,而後添加一個額外的設置,這本質上就是調用函數。

1
2
3
4
5
6
( function doSomething() { 
    return
       name: 'jeff'
       lastName: 'way' 
    }; 
})();

20.原生代碼永遠比庫快

JavaScript庫,例如jQuery和Mootools等能夠節省大量的編碼時間,特別是AJAX操做。已經說過,老是記住,庫永遠不可能比原生JavaScript代碼更快(假設你的代碼正確)。

jQuery的「each」方法是偉大的循環,但使用原生」for」語句老是更快。

 

21.道格拉斯的 JSON.Parse

儘管JavaScript 2(ES5)已經內置了JSON 解析器。但在撰寫本文時,咱們仍然須要本身實現(兼容性)。道格拉斯(Douglas Crockford),JSON之父,已經建立了一個你能夠直接使用的解析器。這裏能夠下載(連接已壞,能夠在這裏查看相關信息http://www.json.org/)。

只需簡單導入腳本,您將得到一個新的全局JSON對象,而後能夠用來解析您的json文件。

1
2
3
4
5
6
var response = JSON.parse(xhr.responseText); 
 
var container = document.getElementById( 'container' ); 
for (var i = 0, len = response.length; i < len; i++) { 
   container.innerHTML += '<li>' + response[i].name + ' : ' + response[i].email + '</li>'
}

22.移除」language」屬性

曾經腳本標籤中的「language」屬性很是常見。

1
2
3
<script type = "text/javascript" language= "javascript"
... 
< /script >

然而,這個屬性早已被棄用,因此請移除(譯者注:html5 中已廢棄,但若是你喜歡,你仍然能夠添加)。

相關文章
相關標籤/搜索