《JavaScript 模式》讀書筆記(2)— 基本技巧1

  • 2020 年 3 月 17 日
  • 筆記

  這篇文章的主要內容,介紹了一些js編程中的基本技巧,其實這些技巧,大家在開發的過程中,或多或少都在使用,或者已經可以熟練的應用於自己的程式碼或項目中了。那麼,這篇文章,就一起來回顧下這些「基本技巧」。

編寫可維護的程式碼

我們想像一下,在我們的工作過程中,要去改一個bug,這個bug可能是由於之前十幾個人維護的項目,沒有規範,沒有JSLint,程式碼就像在大草原上弛聘一樣,隨心所欲,無欲無求。到了今天,剛好你接受了這個項目,測試發現了這個潛藏在系統中已久但今天才暴露的問題。然後,你看著這些程式碼,心裏面問候了程式碼作者的祖宗十六代,但是,不管怎麼樣,你還是要坐下來,安心的,潛心的從這些凌亂的,毫無規則的程式碼中,解決這個bug。

  我相信很多人都遇到過這樣的問題,甚至在一些無規範的公司,企業,項目上,這實在是很普遍的事情(我現在正在經歷的)。那時,你就會發現,編寫可維護的程式碼有多重要。

  易維護的程式碼意味著程式碼具有以下特性:

    1. 閱讀性好。

    2. 具有一致性。

    3. 預見性好。

    4. 看起來如同一個人編寫。

    5. 有文檔。

盡量少用全局變數

  全局變數的問題在於,它們在整個JavaScript應用或Web頁面內共享。它們生存於一個全局命名空間內,總有可能發生命名衝突。

  JavaScript總是在不知不覺中就出人意料地創建了全局變數,其原因在於JavaScript 的兩個特性。第一個特性是JavaScript可直接使用變數,甚至無需聲明。第二個特性是JavaScript有一個暗示全局變數的概念,即任何變數,如果未經聲明,就為全局對象所有(也就像正確生命過的全局變數一樣可以訪問)。比如:

function sum (x,y) {    //反模式:暗示全局變數    result = x + y;    return result;  }

  這個例子中,函數內部的變數result未經聲明就使用了,當然,在簡單環境下,這樣並不會有什麼問題,但是一旦在調用函數後,在外部空間使用了另外的result變數:

function sum(x, y) {      result = x + y;      return result;  }  sum(1, 2)  var result = 6  console.log(result)

  所以,一個首要規則就是,使用var聲明變數。

function sum (x,y) {    var  result = x + y;    return result;  }

  另外一種創建隱式全局變數的反模式式帶有var聲明的鏈式賦值:

//反模式,不要使用  function foo() {      var a = b = 0;        //...  }

  上面的程式碼,由於從右至左的操作符優先順序。所以,上面的程式碼實際是這樣的:

function foo() {      var a = ( b = 0 );        //...  }

  但是,如果對鏈式賦值的所有變數都進行了聲明,那麼就不用擔心會意想不到的創建了全局變數:

function foo() {      var a ,b;      //...      a = b = 0;  }

  另外,假設你的程式碼想要在不同的宿主環境(比如node和window)中都可以跑的很歡快,那麼就一定要注意全局變數的使用。因為,或許在window中不存在的變數,早已被node的全局變數所使用了。

變數釋放時的副作用

  隱含全局變數與明確定義的全局變數有細微的不同,不同之處在於能否使用delete操作符撤銷變數。

  • 使用var創建的全局變數(這類變數在函數外部創建)不能刪除。
  • 不實用var創建的隱含全局變數(儘管它是在函數內部創建)可以刪除。

  這表明隱含全局變數嚴格來講並不是真正的變數,而是全局對象的屬性。屬性可以通過delete操作符刪除,但是變數不可以。

var a = '1';  b = 2;  (function () {      c = 3;  }())  delete a;  delete b;  delete c;    console.log(typeof a)  console.log(typeof b)  console.log(typeof c)

單一var模式

  只使用一個var在函數頂部進行變數聲明是一種非常有用的模式。它的好處在於:

  •   提供方一個單一的地址以查找到函數需要的所有局部變數。
  •       防止出現變數在定義前就被使用的邏輯錯誤。
  •   抱住牢記要聲明變數,以儘可能少的地使用全局變數。
  •       更少的編碼(無論是輸入程式碼還是傳輸程式碼都更少了)。

  比如:

function func() {      var a = 1,          b = 2,          sum = a + b,          obj = {},          i,          j;  }

要記住,所有未初始化,且未聲明的變數,其值都為undefined。這句話不太容易理解,既然未聲明,那就說明不存在啊,沒錯,不存在就是undefined。那既然說到了undefined,簡單說下null的含義,null代表著存在,但是空。

提升:凌散變數的問題

  JavaScript允許在函數的任意地方聲明多個變數,無論在哪裡聲明,效果都等同於在函數頂部進行聲明。這就是所謂的「提升」。當先使用後聲明的時候,就可能會導致邏輯錯誤。對於JavaScript而言,只要變數是在同一個範圍(同一個函數)里,就視為已經聲明,那排是在變數聲明前就使用。比如:

// 反模式  name = 'global'; // 全局變數  function func() {      alert(name); // "未定義"      var name = 'local';      alert(name); // "局部變數"  }  func();

  你以為第一個alert的結果是global么?那麼請再讀一遍加粗的那段話,實際上,程式碼是這樣執行的:

name = 'global'; // 全局變數  function func() {      var name;      alert(name); // "未定義"      name = 'local';      alert(name); // "局部變數"  }  func();

注意:事實上,程式碼處理上分為兩個階段:第一,這個階段創建變數、函數聲明及形式參數。這是解析和進入上線問的階段。第二個階段是程式碼運行時執行過程,創建函數表達和不合格標識符(未定義變數)。但為了實際使用的目的,我們使用了「提升」這個概念,儘管在ECMAScript標準中並不存在。 好了,我們這一篇的內容就到這裡,實際上,僅僅是基本技巧,後面還有不少的內容。我希望篇幅短一點,讀起來不那麼讓人厭煩。

Tags: