14條最佳JavaScript代碼編寫技巧

來源:互聯網
上載者:User

原文:http://club.topsage.com/thread-578906-1-2.html

 

1. 總是使用 ‘var’

在JavaScript中,變數不是全域範圍的就是函數範圍的,使用”var”關鍵詞將是保持變數簡潔明了的關鍵。當聲明一個或者是全域或者是函數級(function-level)的變數,需總是前置”var”關鍵詞,下面的例子將強調不這樣做潛在的問題。

不使用 Var 造成的問題

  1. var i=0; // This is good - creates a global variable
  2. function test() {
  3.  for (i=0; i<10; i++) {
  4.     alert("Hello World!");
  5.  }
  6. }
  7. test();
  8. alert(i); // The global variable i is now 10!

複製代碼

因為變數函數中變數 i 並沒有使用 var 使其成為函數級的變數,在這個例子中它引用了全域變數。總是使用 var 來聲明全域變數是一個很多的做法,但至關重要的一點是使用 var 定義一個函數範圍的變數。下面這兩個方法在功能上是相同的:

正確的函數

  1. function test() {
  2.  var i=0;
  3.  for (i=0; i<10; i++) {
  4.     alert("Hello World!");
  5.  }
  6. }

複製代碼

2. 特性檢測而非瀏覽器檢測

一些代碼是寫來發現瀏覽器版本並基於使用者正使用的用戶端的對其執行不同行為。這個,總的來說,是一個非常糟的實踐。更好的方法是使用特性檢測,在使用一個老瀏覽器可能不支援的進階的特性之前,首先檢測(瀏覽器的)是否有這個功能或特性,然後使用它。這單獨檢測瀏覽器版本來得更好,即使你知道它的效能。你可以在 http://www.jibbering.com/faq/faq_notes/not_browser_detect.html 找到一個深入討論這個問題的文章。

例子:

  1. if (document.getElementById) {
  2.  var element = document.getElementById('MyId');
  3. }
  4. else {
  5.  alert('Your browser lacks the capabilities required to run this script!');
  6. }

複製代碼

3. 使用方括弧記法

當訪問由執行時決定或者包括要不能用”.”號訪問的對象屬性,使用方括弧記法。如果你不是一個經驗豐富的Javascript程式員,總是使用方括弧是一個不錯的做法

對象的屬性由兩種固定的方法來訪問:”.”記法和”[ ]“方括弧記法:

“.”號記法

  1. MyObject.property“[ ]“

複製代碼

方括弧記法

  1. MyObject["property"]

複製代碼

使用”.”號,屬性名稱是硬代碼,不能在執行時改變。使用”[ ]“方括弧,屬性名稱是一個通過計算屬性名稱而來的字串。字串要以是硬代碼,也可能是變數,甚至可以是一個調回一個字母串值的函數。如果一個屬性名稱在執行產生,方括弧是必須,如果你有 “value1″, “value2″, 和 “value3″這樣的屬性,並且想利用變數 i=2來訪問。

這個可以運行:

  1. MyObject["value"+i]

複製代碼

這個不可以:

  1. MyObject.value+i

複製代碼

並且在某些伺服器端環境(PHP、Struts等)下,Form 表單被附加了 [ ] 號來表示 Form 表單在伺服器端必須被當作數組來對待。如此,用”.”號來引用一個包含 [ ] 號的欄位將不會執行,因為 [ ] 是引用一個 Javascript 數組的文法。所以,[ ] 號記法是必須的:

這個可以運行:

  1. formref.elements["name[]"]

複製代碼

這個不可以:

  1. formref.elements.name[]

複製代碼

推薦使用”[ ]“方括弧記法是說當其需要時(明顯地)總是使用它。當不是嚴格需要使用它的時候,它是一個私人的偏好和習慣。一個好的經驗原則是,使用”.”號記法訪問標準的對象屬性,使用”[ ]“方括弧記法訪問由頁面定義的對象屬性。這樣,document["getElementById"]() 是一個完美可行的”[ ]“方括弧記法用法,但 document.getElementById() 在文法上是首選,因為 getElementById 是一個 DOM 規範中定義的一個標準文檔對象屬性。混合使用這兩個記法使哪個是標準對象屬性,哪個屬性名稱是由上下文所定義的,在代碼中顯得清晰明了:

  1. document.forms["myformname"].elements["myinput"].value

複製代碼

這裡,forms 是 document 的一個標準屬性,而表單名 myformname 則是由頁面所定義的。同時,elements 和 value 屬性都是由規範所定義的標準屬性。而 myinput 則是由頁面所定義的。這頁是句法讓人非常容易理解(代碼的內容),是一個推薦遵循的習慣用法,但不是嚴格原則。

4. 避免 ‘eval’

在Javascript中,eval()功能是一個在執行期中執行任意代碼的方法。在幾乎所有的情況下,eval 都不應該被使用。如果它出現在你的頁面中,則表明你所做的有更好的方法。舉一個例子,eval 通常被不知道要使用方括弧記法的程式員所使用。

原則上,”Eval is evil(Eval是魔鬼)”。別使用它,除非你是一個經驗豐富的開發人員並且知道你的情況是個例外。

5. 正確地參考資料表單和表單元素

所有的 HTML 表單都應該有一個 name 屬性。對於 XHTML 文檔來說,name 屬性是不被要求的,但 Form 標籤中應有相應有 id 屬性,並必須用 document.getElementById() 來引用。使用像 document.forms[0] 這樣的索引方法來參考資料表單,在幾乎所有情況下,是一個糟糕的做法。有些瀏覽器把文檔中使用 form 來命名的元素當作一個可用的 form 屬性。這樣並不可靠,不應該使用。

下面這個例子用使用方括弧和正確的對象引用方法來展示如何防止錯誤地引用一個表單的input:

正確參考資料表單 Input:

  1. document.forms["formname"].elements["inputname"]

複製代碼

糟糕的做法:

  1. document.formname.inputname

複製代碼

如果你要引用一個函數裡的兩個表單元素,較好的做法是先引用這個form對象,並將其儲存在變數中。這樣避免了重複查詢以解決表單的引用:

  1. var formElements = document.forms["mainForm"].elements;
  2. formElements["input1"].value="a";
  3. formElements["input2"].value="b";

複製代碼

當你使用 onChange 或者其他類似的事件處理方法,一個好的做法是總是通過一個引來把 input 元素本身引用到函數中來。所有 input 元素都帶有一個對包含其在內的Form表單有一個引用:

  1. <input type="text" name="address" onChange="validate(this)">
  2. function validate(input_obj) {
  3.  // 引用包含這個元素的form
  4.  var theform = input_obj.form;
  5.  // 現在你可以不需要使用硬代碼來參考資料表單自身
  6.  if (theform.elements["city"].value=="") {
  7.     alert("Error");
  8.  }
  9. }

複製代碼

通過對錶單元素的引用來訪問表單的屬性,你可以寫一個不包含硬代碼的函數來引用這個頁面中任何一個有特定名的表單。這是一個非常好的做法,因為函數變得可重用。

避免 ‘with’

Javascript 中的 with 聲明在一個範圍的前端插入一個對象,所以任何屬性/變數的引用將會倚著對象被首先解決。這通常被用作一個避免重複引用的快捷方法:

使用 with 的例子:

  1. with (document.forms["mainForm"].elements) {
  2.  input1.value = "junk";
  3.  input2.value = "junk";
  4. }

複製代碼

但問題在於程式員並沒有方法來驗證 input1 或 input2 實際上已經被當作 Form 元素數組的屬性來解決。它首先以為這些名來檢測屬性,如果找不到,它將會繼續(向下)檢測這個範圍。最後,它在全域對象中嘗試把input1 和 input2 作為一個全域對象來對待,而這以一個錯誤作為結尾。

變通的方法是:建立一個引用來減少引用的對象,並使用它來解決這些引用。

使用一個引用:

  1. var elements = document.forms["mainForm"].elements;
  2. elements.input1.value = "junk";
  3. elements.input2.value = "junk";

複製代碼

7. 在錨點中使用 “onclick” 替代 “javascript: Pseudo-Protocol”

如果你想在 <a> 標籤中觸發Javascript 代碼,選擇 onclick 而非 JavaScript: pseudo-protocol;使用 onclick 來啟動並執行 Javascript 代碼必須返回 ture 或者false(or an expression than evalues to true or false [這句要怎麼翻譯呢? 我是這樣理解的:一個優先性高於true 或 false 的運算式])來返回標籤本身:如果返回 true,則錨點的 href 將被當作一個一般的連結;如果返回 false,則 href 會被忽略。這就是為什麼”return false;” 經常被包含在 onclick 所處理代碼的尾部。

正確句法:

  1. <a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

複製代碼

在這個執行個體中,”doSomething()” 函數(定義於頁面的某個角落)將在被點擊時調用。href 將永遠不會被啟用了Javascript 的瀏覽器訪問。在你可以提醒Javascript 是必須的、而使用者未啟用之的瀏覽器中,文檔 javascript_required.html 才會被載入。通常,當你確保使用者將會開啟 Javascript 支援,為盡量簡化,連結將只包含 href=”#”。 而這個做法是不被鼓勵的。通常有一個不錯的做法是:可以提供沒用啟用 javascript 一個返回本地的頁面。

有時,眾多想要分情況來訪問一個連結。例如,當一個使用者要離開你的一個表單頁面,而想先驗證來確保沒有東西被改變。在這個情況下,你的 onclick 將會訪問一個返回詢問連結是否應該被遵循的函數:

有條件的連結訪問:

  1. <a href="/" onClick="return validate();">Home</a>
  2. function validate() {
  3. return prompt("Are you sure you want to exit this page?");
  4. }

複製代碼

在這個執行個體中,validate() 函數必須只返回 ture 或 false。ture 的時候使用者將被允許問題 home 頁面,或 false 的時候連結不被訪問。這個例子提示確認(其行為),以訪問 ture 或 false,這完全由使用者點擊”確實”或者”取消”決定。

下面是一些”不應該”的例子。如果你在自己的頁面中看到下面這樣的代碼,這是不正確的,需要被修改:

什麼是不應該做的:

  1. <a href="javascript:doSomething()">link</a>
  2. <a href="#" onClick="doSomething()">link</a>
  3. <a href="#" onClick="javascript:doSomething();">link</a>
  4. <a href="#" onClick="javascript:doSomething(); return false;">link</a>

複製代碼

8. 使用一元 ‘+’ 號運算子使類型轉向Number

在Javascript中,”+”號運算子同時充當數學加號和串連符。這會在form表單的域值相加時出現問題,例如,因為Javascript是一個弱類型語言,form 域的值將會被當作數組來處理,而你把它們”+”一起的時候,”+”將被當成串連符,而非數學加號。

有問題的例子:

  1. <form name="myform" action="[url]">
  2. <input type="text" name="val1" value="1">
  3. <input type="text" name="val2" value="2">
  4. </form>
  5. function total() {
  6. var theform = document.forms["myform"];
  7. var total = theform.elements["val1"].value + theform.elements["val2"].value;
  8. alert(total); // 這個將會彈出 "12", 但你想要的是 3!
  9. }

複製代碼

解決這個問題,Javascript 需要一個提示來讓它把這些值當做數字來處理。你可以使用”+”號來把數群組轉換成數字。給變數或者運算式前置一個”+”號將會強制其當作一個數字來處理,而這也將使得數學”+”得以成功應用。

修改好的代碼:

  1. function total() {
  2. var theform = document.forms["myform"];
  3. var total = (+theform.elements["val1"].value) + (+theform.elements["val2"].value);
  4. alert(total); // This will alert 3
  5. }

複製代碼

9. 避免 document.all

document.all 是由Microsoft 的 IE 所引進的,並不是一個標準的 Javascript DOM 特性。儘管大多數新的瀏覽器支援它以支援依賴於它的糟糕代碼,(而)還有很多瀏覽器是不支援的。

並沒有理由其他方法都不適用,而一個老的IE瀏覽器(<5.0)需要支援,而在Javascript中使用 document.all 作為一個折衷方法。 你並不需要使用 document.all 來檢測其是不是IE瀏覽器,因為其他瀏覽器現在一般都支援。

只把 document.all 當做最後的選擇:

  1. if (document.getElementById) {
  2. var obj = document.getElementById("myId");
  3. }
  4. else if (document.all) {
  5. var obj = document.all("myId");
  6. }

複製代碼

一些使用 document.all 的原則:

  • 同嘗試其他方法
  • 當其作為最後的選擇
  • 當需要支援 5.0 版本以下的 IE 瀏覽器
  • 總是使用 “if (document.all) { }” 來查看是否支援.

10. 不要在指令碼代碼塊中使用HTML注釋

在 Javascript 的舊日子(1995)裡,諸如 Netscape 1.0 的一些瀏覽器並不支援或認識 <script>標籤。所以,當 Javascript 第一次被發布,需要有一個技術來讓實些代碼不被當做文本顯示於舊版瀏覽器上。有一個”hack” 是在代碼中使用 HTML 注釋來隱藏這些代碼。

使 HTML 注釋並不好:

  1. <script language="javascript">
  2. <!--
  3.  // code here
  4. //-->
  5. </script>

複製代碼

在今天,沒有任何一個常用的瀏覽器會忽略掉 <script> 標籤。因此,再沒必要隱藏 Javascript 原始碼。事實上,它還可以因為下面的理由,被認為是無益的:

  • 在 XHTML 文檔中,原始碼將向所有瀏覽器隱藏並被渲染成無用的(內容);
  • 在 HTML 注釋並不允許 ,這個會讓任何遞減操作將失效。

11. 避免亂用全域命名空間

一般很少需要全部變數和函數。全域使用將可能導致 Javascript 源檔案文檔衝突,和代碼中止。因此,一個好的做法是在一個全域命名空間內採用函數性的封裝。有多個方法可以完成這個任務,有此相對比較複雜。最簡單的方法是建立一個全域對象,並把屬性和方法指派給這個對象:

建立一個命名空間:

  1. var MyLib = {}; // global Object cointainer
  2. MyLib.value = 1;
  3. MyLib.increment = function() { MyLib.value++; }
  4. MyLib.show = function() { alert(MyLib.value); }
  5. MyLib.value=6;
  6. MyLib.increment();
  7. MyLib.show(); // alerts 7

複製代碼

命名空間也可以使用 Closures(閉包?) 來建立,並且 Private Member Variables (私人變數?) 也可以偽裝於 Javascript中。

12. 避免同步的 ‘Ajax’ 調用

當使用”Ajax”請求時,你要麼選擇非同步模式,要麼使用同步模式。當瀏覽器行為可以繼續執行,非同步模式將請求放在後台執行,同步模式則會等待請求完成後才繼續。

應該避免同步模式做出的請求。這些請求將會對使用者禁用瀏覽器,直至請求返回。一旦伺服器忙,並需要一段時間來完成請求,使用者的瀏覽器(或者 OS)將不能做任何其他的事,直至請求逾時。

如果你覺得自己的情況需要同步模式,最大的可能是你需要時間來重新想一下你的設計。很少(如果有的話)實際上需要同步模式的 Ajax 請求。

13. 使用 JSON

當需要將資料結構儲存成純文字,或者通過 Ajax 發送/取回資料結構,儘可能使用 JSON 代替 XML。JSON (JavaScript Object Notation) 是一個更簡潔有效資料存放區格式,並且不依賴任何語言(and is a language-neutral)。

14. 使用正確的 <script> 標籤

不贊成在 <script> 中的使用LANGUAGE 屬性。一個合適的方式是建立如下的 Javascript 代碼塊:

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

複製代碼

 

原文:http://club.topsage.com/thread-578906-1-2.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.