重構 - 代碼優化技巧

本文爲飢人谷講師方方原創文章,首發於 前端學習指南html

如下是我《JS深刻淺出》第6課的講義,若是對你有幫助點個贊便可前端

此次課講的是「如何提升代碼的可讀性」,跟前端關係不大,是寫代碼的廣泛技巧。程序員

注意咱們講得不是「如何提升代碼的性能」。面試

代碼優化基本原則

  1. 易讀性優先
  2. 若是不是性能瓶頸,就不要爲了性能而改寫代碼
  3. 複雜性守恆原則:不管你怎麼寫代碼,複雜性都是不會消失的

推論:若是邏輯很複雜,那麼代碼看起來就應該是複雜的。若是邏輯很簡單,代碼看起來就應該是簡單的。編程

命名

程序員三大難題緩存

  1. 變量命名
  2. 緩存失效
  3. 循環邊界

可見變量命名的重要性。微信

網上有不少命名規範,你們能夠參考。本節課只講基本原則。dom

1、注意詞性函數

  • 普通變量/屬性用「名詞」
var person = {
      name: 'Frank'
  }
  var student = {
      grade: 3,
      class: 2
  }
  • bool變量/屬性用「形容詞」或者「be動詞」或者「情態動詞」或者「hasX」
var person = {
      dead: false, // 若是是形容詞,前面就不必加 is,好比isDead 就很廢話
      canSpeak: true, //情態動詞有 can、should、will、need 等,情態動詞後面接
動詞
      isVip: true, // be 動詞有 is、was 等,後面通常接名詞
      hasChildren: true, // has 加名詞
  }
  • 普通函數/方法用「動詞」開頭
var person = {
      run(){}, // 不及物動詞
      drinkWater(){}, // 及物動詞
      eat(foo){}, // 及物動詞加參數(參數是名詞)
  }
  • 回調、鉤子函數用「介詞」開頭,或用「動詞的如今完成時態」
var person = {
      beforeDie(){},
      afterDie(){},
      // 或者
      willDie(){}
      dead(){} // 這裏跟 bool 衝突,你只要不一樣時暴露 bool dead 和函數 dead 就行,怕衝突就用上面的 afterDie
  }
  button.addEventListener('click', onButtonClick)
  var component = {
      beforeCreate(){},
      created(){},
      beforeMount(){},
      mounted(){},
      beforeUpdate(){},
      updated(){},
      activated(){},
      deactivated(){},
      beforeDestroy(){},
      destroyed(){},
      errorCaptured(){}
  }
  • 容易混淆的地方加前綴
div1.classList.add('active') // DOM 對象
  div2.addClass('active') // jQuery 對象
  不如改爲
  domDiv1 或 elDiv1.classList.add('active')
  $div2.addClass('active')

屬性訪問器函數能夠用名詞性能

$div.text() // 實際上是 $div.getText()
  $div.text('hi') // 實際上是 $div.setText('hi')

2、注意一致性

  • 介詞一致性

若是你使用了 before + after,那麼就在代碼的全部地方都堅持使用
若是你使用了 before + 完成時,那麼就堅持使用
若是你改來改去,就「不一致」了,不一致將致使「不可預測」

  • 順序一致性

好比 updateContainerWidth 和 updateHeightOfContainer 的順序就使人很彆扭,一樣會引起「不可預測」

  • 表裏一致性

函數名必須完美體現函數的功能,既不能多也不能少。
好比

function getSongs(){
      return $.get('/songs).then((response){
          div.innerText = response.songs
      })
  }

就違背了表裏一致性,getSongs 表示獲取歌曲,並無暗示這個函數會更新頁面,可是實際上函數更新了 div,這就是表裏不一,正確的寫法是

  • 要麼糾正函數名
function getSongsAndUpdateDiv(){
      return $.get('/songs).then((response){
          div.innerText = response.songs
      })
  }
  • 要麼寫成兩個函數
function getSongs(){
      return $.get('/songs)
  }
  function updateDiv(songs){
      div.innerText = response.songs
  }
  getSongs().then((response)=>{
      updateDiv(response.songs)
  })
  • 時間一致性

有可能隨着代碼的變遷,一個變量的含義已經不一樣於它一開始的含義了,這個時候你須要及時改掉這個變量的名字。
這一條是最難作到的,由於寫代碼容易,改代碼難。若是這個代碼組織得很差,極可能會出現牽一髮而動全身的狀況(如全局變量就很難改)

改代碼

若是你的代碼有單元測試,那麼改起來就很放心。若是沒有單元測試,就須要用「小步快跑」的策略來修改。

小步快跑的意思是說,每次只修改一點點,測試經過後,再修改一點點,再測試,再修改一點點……如此反覆。

那麼如何修改一點點呢?《重構》這本書介紹了不少方法,可是講得有點抽象的,若是你有時間能夠看看。

我這裏只說兩個經久不衰的方法。

1、使用函數來改代碼

步驟:

  1. 將一坨代碼放到一個函數裏
  2. 將代碼依賴的外部變量做爲參數
  3. 將代碼的輸出做爲函數的返回值
  4. 給函數取一個合適的名字
  5. 調用這個函數並傳入參數
  6. 這個函數裏的代碼若是超過 5 行,則依然有優化的空間,請回到第 1 步

2、使用對象來改代碼

若是使用了函數改造法改造後,發現有太多的小函數,則可使用對象將這些函數串起來。

記得咱們講過「this 是函數和對象的橋樑」嗎,咱們會用 this 來串聯這個對象和全部函數。

最終代碼:http://js.jirengu.com/mimazab...

一些固定的套路

  1. 表驅動編程(《代碼大全》裏說的)

全部一一對應的關係均可以用表來作

  1. 自說明代碼(以 API 參數爲例)

把別人關心的東西放在顯眼的位置

bad smell(壞味道)

有些代碼能夠用,可是很「臭」。

哪些代碼是有壞味道的

  1. 表裏不一的代碼
  2. 過期的註釋
  3. 邏輯很簡單,可是看起來很複雜的代碼
  4. 重複的代碼
  5. 類似的代碼
  6. 老是一塊兒出現的代碼

破窗效應

此理論認爲環境中的不良現象若是被聽任存在,會誘令人們仿效,甚至變本加厲。一幢有少量破窗的建築爲例,若是那些窗不被修理好,可能將會有破壞者破壞更多的窗戶。最終他們甚至會闖入建築內,若是發現無人居住,也許就在那裏定居或者縱火。一面牆,若是出現一些塗鴉沒有被清洗掉,很快的,牆上就佈滿了亂七八糟、不堪入目的東西;一條人行道有些許紙屑,不久後就會有更多垃圾,最終人們會視若理所固然地將垃圾順手丟棄在地上。這個現象,就是犯罪心理學中的破窗效應。

程序員要作到:只要是通過你手的代碼,都會比以前好一點。

加微信號: astak10或者長按識別下方二維碼進入前端技術交流羣 ,暗號:寫代碼啦

每日一題,每週資源推薦,精彩博客推薦,工做、筆試、面試經驗交流解答,免費直播課,羣友輕分享... ,數不盡的福利免費送

相關文章
相關標籤/搜索