編寫高質量JavaScript代碼的一些建議
來自: http://www.ido321.com/1666.html
在Medium上看到了兩篇關于寫高質量JavaScript代碼的文章,覺得不錯,特此搬過來,記下一筆,以待后續查閱。
JavaScript 作為最受歡迎的編程語言之一,被廣泛應用在各個領域:網站、服務端、游戲、操作系統等。跟人類一樣,編程語言也是隨著時間的推移慢慢進化的,而在進化的過程中,其創建者也會做出一些現在看來很糟糕的決定,給語言加入一些詬病。但是,開發人員也花費了很多時間去總結了很多最佳實踐來消除語言自身詬病帶來的影響。如果沒有特別的緣由,就應該遵循這些最佳實踐,而不是重新造輪子。
1、使用var聲明變量
使用 var ,會在變量定義之處所在的作用域定義一個變量,如果忽略了 var ,則該變量會被添加到全局環境(window 對象)。所有人都知道,全局變量非常邪惡。
2、嚴格模式
在JavaScript文件中以'use strict'(雙引號)開始,這能阻止使用 JavaScript 的一些不好的實踐,想了解更多關于嚴格模式的信息,戳此: Strict mode-Mozilla Developer Network
3、使用IIFE–Immediately Invoked Function Expression
將代碼放進一個立即執行函數中,這會對 JavaScript 文件中定義的變量和函數進行封裝而不會被添加到全局環境,也不會污染全局環境。想了解更多,戳此: IIFE
4、使用駝峰表示法
編程語言是寫給人看的,這也是它們為什么是用英語寫的原因。因此,代碼應該是可讀和可理解的。為了使代碼可讀和可理解,應該一致的方式來編寫代碼。遵循慣例,大多數的 JavaScript 應用,工具和庫采用駝峰式,遵循這個風格是很重要的,這能避免我們的代碼看起來很怪異。遵循一致慣例,也不會對那些想使用你代碼的開發者造成困惑。
5、嵌套函數定義并不令人厭惡
在函數作用域需要的地方,可以使用嵌套函數定義,從長遠來看,它能保持代碼干凈和模塊化。
6、使用 === 和!==
在 JavaScript 中, == 和 != 操作符是不會檢查類型,因而會返回意向不到的結果。想了解更多,戳此: Read More
(在 你有必要知道的 25 個 JavaScript 面試題 的第一題就有坑)
7、和使用單引號的人保持一致,而不是雙引號
和使用單引號的 JavaScript 開發人員保持一致,跟他們一樣,使用單引號。
8、使用Linter
Linting 是檢查源代碼以及代碼風格的一個過程。 –網絡
Get JSHint to your favorite Code Editor
9、代碼格式化
<——-我是分割線——>
上面一些建議有助于你寫出更好的 JavaScript 代碼(Write Better JavaScript),接下來會為如何寫出運行更快的 JavaScript 代碼提供建議參考(Write Fast JavaSctipt),每一個建議都帶有 jsPerf 的測試。
10、避免類型轉換
JavaScript 是動態型的,但如要提高代碼運行速度,就不要使用這個特性,而是應該讓變量類型保持一致。這同樣適用于數組,不要在數組中混合使用不同類型。
{
var x = '2';
var y = 5;
x = 2;
x + y;
}
11、String轉Number
parseInt & parseFloat 是將(數字)字符串轉換成 Number 類型的最好方式嗎?
// Different ways of parsing integer/float from strings
parseFloat("100")
+"100"
// integer only
parseInt("100", 10)
"100"|0
"100" >> 0
"100" << 0
//Only works for positive numbers
"100" >>> 0
parseInt test ~ parseFloat test
火狐優化了位操作符,其運行速度比 parseInt 和 + 操作符快了 99%,但 Chrome 沒有做優化,運行速度還比 parseInt 慢 68%。
parseFloat 則在二者上比 + 操作符都快(火狐快28%,Chrome 快39%)
12、不要重構對象
重構對象是很昂貴的操作,遵循下面的建議來避免:
不使用 delete 操作符
刪除一個屬性,用 delete 會比通過 null 賦值慢很多,在火狐和 Chrome 中, null 賦值會快 99%,因為它不會修改對象的結構,但是 delete 會。
不要添加屬性
定義對象后,不要隨后給對象添加屬性,而是一開始就應該定義好對象的結構模式,這樣運行速度會快很多(火狐上快 100%,Chrome 上快 89%)
dynamic properties vs pre-defined structure
13、字符串拼接
字符串拼接是相當昂貴的操作,但最好的實現方式是啥呢?肯定不是 Array.prototype.join 。
字符串拼接運行在不同瀏覽器上的結果差別很大,我推薦你自己在不同瀏覽器上運行測試來找到合適的方式。最快的情況下:在火狐上,重關聯字符串(Reassociating strings)是運行最快的方式;對于 Chrome,在 constant fold 的幫助下,使用 Array.prototype.join 是最快的。在二者上的最慢情況似乎是使用 String.prototype.concat 和 + 操作符。
14、使用正確的正則方法
在 RegExp.prototype.test 和 String.prototype.search 之間是有性能差異的,看看哪個運行更快:
看上去 RegExp.prototype.test 比 String.prototype.search 快很多,這是因為二者的運行條件并不是完全一樣的,它們是不同的,關于這個的討論超出了文章范圍,你可以看看這個問題: Stack Overflow
在尋找存在的字符串時, RegExp.prototype.test 更快,可能是因為它不返回匹配字符串的索引,而 String.prototype.search 僅僅用于返回匹配字符串的索引。
你不應該使用 RegExps 來查找子字符串的索引,而是應該使用 String.prototype.indexOf 。
String.prototype.search vs String.prototype.indexOf
另一個有趣的基準是 String.prototype.indexOf vs RegExp.prototype.test ,我個人期待后者會更快一點,但這出現在火狐中,在Chrome中相反。在火狐中,后者快 32%;然后在 Chrome 中,前者快 33%。這種情況,就選擇你喜歡的吧。
15、聲明 & 傳遞局部作用域變量
當調用一個函數時,瀏覽器會進行 作用域查找 ,這個時間花銷跟瀏覽器要查找的作用域數有關。不要依賴全局/高層作用域變量,而是創建局部作用域變量,然后傳遞給函數。查找的作用域數越少,就運行更快。
internal scope vs higher scope vs global
16、不要一切都離不開jQuery
很多開發者使用 jQuery 來完成很簡單的任務,我的意思是,不要因為項目引入了 jQuery,就必須用它,想想,$val()是一直有必要使用嗎?看個示例:
$('input').keyup(function() {
if($(this).val() === 'blah') { ... }
});
學會用平常的 JavaScript 去修改 DOM 的一個最重要的理由是,能寫出更高效的代碼。
同樣的條件,普通的 JavaScript 代碼運行更快,看測試: JSPerf Test
$('input').keyup(function() {
if(this.value === 'blah') { ... }
});
17、對于耗時任務,使用 Web Workers
如果你有非常耗時的計算任務,如圖像處理,最好使用 Web Workers 讓瀏覽器在后臺線程中運行這個任務,并且異步返回處理結果,而不是掛起線程。
</article>