JavaScript 最佳實踐:幫你提升程式碼質量
每天學一些新東西可以讓一個理性之人走上不凡之路。而作為開發人員,不斷的學習新東西則是我們工作的一部分, 不論這些新東西是不是來源於積極的學習經驗。
在本篇教程中,我將指出一些重要的 JavaScript 最佳實踐,讓你不必去用另外一種艱難的方式來了解它們。準備好去升級你的程式碼吧!
1. 避免對全域性作用域的汙染
宣告變數是一件很有趣的事情。有時候即使你不想這樣做,但也有可能會定義出全域性變數。在如今的瀏覽器中,全域性變數都被儲存在 window 物件中。而因為有許多的東西都在那個裡面,所以你有可能把一些預設值都給覆蓋掉了。
假設你有一個 HTML 檔案,裡面包含了一個 <script> 標記,而這個標記內含 (或者通過引用一個 JavaScript 檔案而載入) 如下內容:
var foo = 42; console.log(foo);
這段程式碼很明顯會讓控制檯輸出 42。不過因為程式碼並不是放到一個函式裡面去執行的,因此其執行的上下文就會是全域性的那個。因此,變數就會被附加到 window 物件上。這就意味著 window.foo 的值也會是 42。
這樣是挺危險的,因為你可以把已經存在的全域性變數給覆蓋掉:
function print () { // do something } print();
當執行 window.print (或者只是執行 print) 的時候, 它不會開啟列印彈窗,因為我們已經將原生的列印彈窗邏輯給覆蓋掉了。
解決這個問題的方案相當簡單; 我們需要一個會在定義後立即被呼叫到的閉包函式, 如下所示:
// Declare an anonymous function (function () { var foo = 42; console.log(window.foo); // → undefined console.log(foo); // → 42 })(); //^ and call it immediately
或者你也可以選擇將 window 以及其它全域性的東西(例如 document)都作為引數傳給那個函式(這樣做也可能對效能會有所提升):
(function (global, doc) { global.setTimeout(function () { doc.body.innerHTML = "Hello!"; }, 1000); })(window, document);
因此你得使用閉包函式來避免建立出什麼全域性的東西來。注意在這裡因為要專注於程式碼本身,所以我不會在後面的程式碼片段中使用閉包函式。
提示: browserify 是另外一種避免建立全域性變數的方式。它採用了你在 Node.js 同樣會用到的 require 函式的方式。
順便說一下, Node.js 會自動將你的檔案封裝進函式裡面。它們看起來先下面這樣:
(function (exports, require, module, __filename, __dirname) { // ...
因此,如果你認為 require 函式式全域性的,好吧,並不是。它無非就是一個函式的引數。
你知道嗎?
因為 window 物件包含了所有的全域性變數,又因為它自己也是全域性的,因此 window 自己內部也引用了它自己:
window.window.window // => Window {...}
這是一位 window 物件是一個迴圈引用物件。下面展示瞭如何建立這樣的一個物件:
// Create an object var foo = {}; // Point a key value to the object itself foo.bar = foo; // The `foo` object just became a circular one: foo.bar.bar.bar.bar // → foo
或者,為了展示你對 JavaScript 的無限的熱愛之情,你可以當回發燒友,程式碼如下:
是的,你可以幾乎沒完沒了(也有可能會等到瀏覽器崩潰)的展開這個物件。
2. 好的 use strict 使用習慣
要嚴格使用 use strict! 這無非就是在你的程式碼中加了一行,給你的指令碼增加更多的小把戲。
例如:
// This is bad, since you do create a global without having anyone to tell you (function () { a = 42; console.log(a); // → 42 })(); console.log(a); // → 42
使用 use strict, 你就可以獲取到更多一點的錯誤資訊:
(function () { "use strict"; a = 42; // Error: Uncaught ReferenceError: a is not defined })();
你可能想知道為什麼可以將 "use strict" 放在封裝函式的外面。這的確是可以的,不過這樣它就會被應用到全域性。這還不是太壞,但是如果有程式碼是來自於其它的庫,或者你要把所有的東西都打包到一個檔案裡面去的話,這樣做就會有影響的。
3. 嚴格相等
這個比較簡短。如果你在 JavaScript 中 (像其它的程式語言中那樣)使用 == 來比較 a 和 b,可能會發現其執行的方式有點怪: 如果你有一個字串和一個數字如下,它們會相等 (==):
"42" == 42 // → true
對於一些明顯的緣故 (例如驗證操作), 最好就是使用嚴格等於(===):
"42" === 42 // → false
4. 使用 && 和 || 來製造點小把戲
根你需要做的事情,你可以使用邏輯操作符來讓程式碼更簡短。
取預設值
"" || "foo" // → "foo" undefined || 42 // → 42 // Note that if you want to handle 0 there, you need // to check if a number was provided: var a = 0; a || 42 // → 42 // This is a ternary operator—works like an inline if-else statement var b = typeof a === "number" ? a : 42; // → 0
不用拿 if 表示式來檢查某些東西是不是為真的,你也可以簡單地這樣做:
expr && doSomething(); // Instead of:
if (expr) { doSomething(); }
如果你需要通過 doSomething(): 來決定返回的結果,這樣做更酷:
function doSomething () { return { foo: "bar" }; }
var expr = true;
var res = expr && doSomething(); res && console.log(res); // → { foo: "bar" }
你可能不會贊同我在這方面的看法,但像我說的這樣做其實效果更理想。如果你並不想像這樣來對你的程式碼進行混淆,但其實這就是那些 JavaScript 簡化器實際會做的事情。
如果你來問我,我會說這樣做雖然讓程式碼更加簡短了,但仍然是可讀的。
5. 對值的型別進行轉化
有幾種方法可以根據你的想法來進行轉化。最常用的方式有如下這些:
// From anything to a number var foo = "42"; var myNumber = +foo; // shortcut for Number(foo) // → 42 // Tip: you can convert it directly into a negative number var negativeFoo = -foo; // or -Number(foo) // → -42 // From object to array // Tip: `arguments` is an object and in general you want to use it as array var args = { 0: "foo", 1: "bar", length: 2 }; Array.prototype.slice.call(args) // → [ 'foo', 'bar' ] // Anything to boolean /// Non non p is a boolean p var t = 1; var f = 0; !!t // → true !!f // → false /// And non-p is a boolean non-p !t // → false !f // → true // Anything to string var foo = 42; "" + foo // shortcut for String(foo) // → "42" foo = { hello: "world" }; JSON.stringify(foo); // → '{ "hello":"world" }' JSON.stringify(foo, null, 4); // beautify the things // → // '{ // "hello": "world" // }' // Note you cannot JSON.stringify circular structures JSON.stringify(window); // ⚠ TypeError: JSON.stringify cannot serialize cyclic structures.
6. 程式碼風格/風格指南
在新的專案中要讓所有的檔案都遵循相同的程式碼風格。對於現有的專案,就使用現有的程式碼風格, 除非你就只是決定要變一變它的風格(提示: 同你的搭檔就此進行一下討論)。甚至你要建立和記錄你自己的程式碼風格,然後一直去遵循它。
現有的一些不同的程式碼風格如下:
-
... 也還有其它的一些
額外的福利小提示:
你應該記住的其它一些重要的 JavaScript 最佳實踐就是那些能幫助你對程式碼進行格式化的工具。下面是其中的一些:
-
js-beautify: 美化你的程式碼
-
UglifyJS(2): 混淆/最小化你的程式碼
-
jshint: 檢測 JavaScript 程式碼中的錯誤或者潛在問題
-
jscs: 可以配置的樣式指南檢測器
最後一個就是: 不要總是 console.log,要對你的程式碼進行除錯。
祝你程式設計愉快!
原文地址:https://www.codementor.io/johnnyb/tutorials/javascript-best-practices-du107mvud
相關文章
- 6 個重構方法可幫你提升 80% 的程式碼質量
- 6 個重構方法可幫你提升 80% 的程式碼質量(轉)
- 掌握TypeScript:10個最佳實踐提高程式碼質量.mdTypeScript
- 掌握這些程式碼安全檢視方法,提升你的程式碼質量
- 前端程式碼質量的思考與實踐前端
- Litmus程式碼質量平臺實踐總結
- 程式碼質量(權威精選植根於開發實踐的最佳讀物)
- 騰訊質量效能提升最佳實踐:智慧自動化測試探索和建設
- 如何提升 Web 應用的程式碼質量Web
- JavaScript 最佳實踐JavaScript
- 程式設計師必看:如何充分利用程式碼審查提升你的程式碼質量?程式設計師
- 前端程式碼質量-圈複雜度原理和實踐前端複雜度
- 《程式碼整潔之道》精華速覽,助你提升程式碼質量
- JavaScript 程式碼靜態質量檢查JavaScript
- 利用SonarCloud和Azure DevOps提升程式碼質量Clouddev
- JavaScript最佳實踐:效能JavaScript
- 程式碼審查最佳實踐
- 文章錯別字檢測,提升你的內容質量,幫你進行內容分發
- OCLint 實現 Code Review - 給你的程式碼提提質量View
- fitbit運動手環有了新特性 升級App能幫你提升睡眠質量APP
- 前端質量提升利器-馬可程式碼覆蓋率平臺前端
- React 程式碼共享最佳實踐方式React
- React 整潔程式碼最佳實踐React
- 24個javascript最佳實踐JavaScript
- JavaScript 開發最佳實踐JavaScript
- 程式碼重構之道:消滅冗長的if語句,提升程式碼質量
- 如何利用大模型提升前端研發效率和程式碼質量大模型前端
- 10 個你需要了解的最佳 javascript 開發實踐JavaScript
- dart系列之:dart程式碼最佳實踐Dart
- [譯] 程式碼審查之最佳實踐
- JavaScript 專案最佳實踐指南JavaScript
- 《Effective JavaScript 編寫高質量JavaScript程式碼的68個有效方法》JavaScript
- 提升開發效率,小程式容器來幫你
- 三年0故障總結,提升程式碼質量的祕訣
- Sonar程式碼質量管理
- 程式碼質量管理-Sonar
- Vert.x 程式碼結構最佳實踐
- 編寫優雅程式碼的最佳實踐