JavaScript 最佳實踐:幫你提升代碼質量

字號+ 編輯: 种花家 修訂: 种花家 來源: JavaScript最佳实践 2023-09-12 我要說兩句(0)

在本篇教程中,我將指出一些重要的 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. 代碼風格/風格指南

在新的項目中要讓所有的文档都遵循相同的代碼風格。對於現有的項目,就使用現有的代碼風格, 除非你就只是決定要變一變它的風格(提示: 同你的搭档就此進行一下討論)。甚至你要創建和記錄你自己的代碼風格,然後一直去遵循它。

現有的一些不同的代碼風格如下:

Google JavaScript 風格指南

airbnb/javascript

... 也還有其它的一些

我的風格指南

額外的福利小提示:

你應該記住的其它一些重要的 JavaScript 最佳實踐就是那些能幫助你對代碼進行格式化的工具。下面是其中的一些:

js-beautify: 美化你的代碼

UglifyJS(2): 混淆/最小化你的代碼

jshint: 檢測 JavaScript 代碼中的錯誤或者潛在問題

jscs: 可以配置的樣式指南檢測器

最後一個就是: 不要總是 console.log,要對你的代碼進行調試。

閲完此文,您的感想如何?
  • 有用

    0

  • 沒用

    0

  • 開心

    0

  • 憤怒

    0

  • 可憐

    0

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • JS如何防止父節點的事件運行

  • nodejs編寫一個簡單的http請求客戶耑代碼demo

  • 說一則爲什麽後耑開發人員不選擇node.js的原因

  • 使用Sublime Text3 開發React-Native的配置

我要說說
網上賓友點評