<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          11個(gè) Javascript 小技巧幫你提升代碼質(zhì)量

          共 12378字,需瀏覽 25分鐘

           ·

          2021-01-25 20:43

          轉(zhuǎn)自:掘金 - alanyf

          Javascript 常用代碼優(yōu)化和重構(gòu)的方法

          簡(jiǎn)介

          主要介紹以下幾點(diǎn):

          1. 提煉函數(shù)
          2. 合并重復(fù)的條件片段
          3. 把條件分支語句提煉成函數(shù)
          4. 合理使用循環(huán)
          5. 提前讓函數(shù)退出代替嵌套條件分支
          6. 傳遞對(duì)象參數(shù)代替過長的參數(shù)列表
          7. 少用三目運(yùn)算符
          8. 合理使用鏈?zhǔn)秸{(diào)用
          9. 分解大型類
          10. 活用位操作符
          11. 純函數(shù)

          本文會(huì)不斷更新,不足之處歡迎補(bǔ)充。

          1. 提煉函數(shù)

          好處:

          • 避免出現(xiàn)超大函數(shù)。
          • 獨(dú)立出來的函數(shù)有助于代碼復(fù)用。
          • 獨(dú)立出來的函數(shù)更容易被覆寫。
          • 獨(dú)立出來的函數(shù)如果擁有一個(gè)良好的命名,它本身就起到了注釋的作用。
          • 語義化將多段分離的邏輯放在不同的函數(shù)中實(shí)現(xiàn),可以使代碼邏輯清晰,清楚的看到每一步在做什么。

          代碼舉例:

          實(shí)現(xiàn)獲取數(shù)據(jù),然后操作dom顯示數(shù)據(jù),最后添加事件

          • 函數(shù)提煉前
          // 邏輯都寫在一起,需要將所有邏輯看完才知道這段代碼是干嘛的,局部邏輯無法復(fù)用
          function main({
              $.ajax.get('/getData').then((res) => {
                  const ul = document.getElementById('ul');
                  ul.innerHTML = res.list.map(text => `<li class="li">${text}</li>`).join('\n');
                  const list = document.getElementsByClassName('li');
                  for (let i = 0; i < list.length; i ++) {
                      list[i].addEventListener('focus', () => {
                          // do something
                      });
                  }
              });
          }


          • 函數(shù)提煉后
          function getData({
              return $.ajax.get('/getData').then((res) => res.data.list);
          }
          function showList(list{
              const ul = document.getElementById('ul');
              ul.innerHTML = list.map(text => `<li class="li">${text}</li>`).join('\n');
          }
          function addEvent({
              const list = document.getElementsByClassName('li');
              for (let i = 0; i < list.length; i ++) {
                  list[i].addEventListener('focus', () => {
                      // do something
                  });
              }
          }
          // 邏輯清晰,一眼讀懂每一步在做什么,某些提煉出來的函數(shù)還可以被復(fù)用
          async function main({
              const list = await getData(); // 獲取數(shù)據(jù)
              showList(list); // 顯示頁面
              addEvent(); // 添加事件
          }


          2. 合并重復(fù)的條件片段

          如果一個(gè)函數(shù)體內(nèi)有一些條件分支語句,而這些條件分支語句內(nèi)部散布了一些重復(fù)的代碼,那么就有必要進(jìn)行合并去重工作。

          // 合并前
          function main( currPage ){
              if ( currPage <= 0 ){
                  currPage = 0;
                  jump( currPage ); // 跳轉(zhuǎn)
              }else if ( currPage >= totalPage ){
                  currPage = totalPage;
                  jump( currPage ); // 跳轉(zhuǎn)
              }else{
                  jump( currPage ); // 跳轉(zhuǎn)
              }
          };

          // 合并后
          function main( currPage ){
              if ( currPage <= 0 ){
                  currPage = 0;
              }else if ( currPage >= totalPage ){
                  currPage = totalPage;
              }
              jump( currPage ); // 把jump 函數(shù)獨(dú)立出來
          };


          3. 把條件分支語句提煉成函數(shù)

          復(fù)雜的條件分支語句是導(dǎo)致程序難以閱讀和理解的重要原因,而且容易導(dǎo)致一個(gè)龐大的函數(shù)。有時(shí)可以將條件分支語句提煉成語義化的函數(shù),使代碼更加直觀,邏輯清晰。

          // 根據(jù)不同季節(jié)決定打折力度
          function getPrice( price ){
              var date = new Date();
              if ( date.getMonth() >= 6 && date.getMonth() <= 9 ){ // 夏天
                  return price * 0.8;
              }
              return price;
          };


          // 是否是夏天
          function isSummer(){
              var date = new Date();
              return date.getMonth() >= 6 && date.getMonth() <= 9;
          };
          // 提煉條件后
          function getPrice( price ){
              if ( isSummer() ){
                  return price * 0.8;
              }
              return price;
          };


          4. 合理使用循環(huán)

          如果多段代碼實(shí)際上負(fù)責(zé)的是一些重復(fù)性的工作,那么可以用循環(huán)代替,使代碼量更少。

          // 判斷是什么瀏覽器
          function getBrowser(){
              const str = navigator.userAgent;
              if (str.includes('QQBrowser')) {
           return 'qq';
              } else if (str.includes('Chrome')) {
           return 'chrome';
              } else if (str.includes('Safari')) {
                  return 'safri';
              } else if (str.includes('Firefox')) {
                  return 'firefox';
              } else if(explorer.indexOf('Opera') >= 0){
                  return 'opera';
              } else if (str.includes('msie')) {
                  return 'ie';
              } else {
                  return 'other';
              }
          };


          // 循環(huán)判斷,將對(duì)應(yīng)關(guān)系抽象為配置,更加清晰明確
          function getBrowser(){
              const str = navigator.userAgent;
              const list = [
                  {key'QQBrowser'browser'qq'},
                  {key'Chrome'browser'chrome'},
                  {key'Safari'browser'safari'},
                  {key'Firefox'browser'firefox'},
                  {key'Opera'browser'opera'},
                  {key'msie'browser'ie'},
              ];
              for (let i = 0; i < list.length; i++) {
                  const item = list[i];
                  if (str.includes(item.key)) {return item.browser};
              }
              return 'other';
          }



          5. 提前讓函數(shù)退出代替嵌套條件分支

          讓函數(shù)變成多出口提前返回,替換嵌套條件分支。

          function del( obj ){
              var ret;
              if ( !obj.isReadOnly ){ // 不為只讀的才能被刪除
                  if ( obj.isFolder ){ // 如果是文件夾
                      ret = deleteFolder( obj );
                  }else if ( obj.isFile ){ // 如果是文件
                      ret = deleteFile( obj );
                  }
              }
              return ret;
          };

          function del( obj ){
              if ( obj.isReadOnly ){ // 反轉(zhuǎn)if 表達(dá)式
                  return;
              }
              if ( obj.isFolder ){
                  return deleteFolder( obj );
              }
              if ( obj.isFile ){
                  return deleteFile( obj );
              }
          };


          6. 傳遞對(duì)象參數(shù)代替過長的參數(shù)列表

          函數(shù)參數(shù)過長那么就增加出錯(cuò)的風(fēng)險(xiǎn),想保證傳遞的順序正確就是一件麻煩的事,代碼可讀性也會(huì)變差,盡量保證函數(shù)的參數(shù)不會(huì)太長。如果必須傳遞多個(gè)參數(shù)的話,建議使用對(duì)象代替。

          一般來說,函數(shù)參數(shù)最好不要超過3個(gè)

          function setUserInfo( id, name, address, sex, mobile, qq ){
              console.log( 'id= ' + id );
              console.log( 'name= ' +name );
              console.log( 'address= ' + address );
              console.log( 'sex= ' + sex );
              console.log( 'mobile= ' + mobile );
              console.log( 'qq= ' + qq );
          };
          setUserInfo( 1314'sven''shenzhen''male''137********'377876679 );

          function setUserInfo( obj ){
              console.log( 'id= ' + obj.id );
              console.log( 'name= ' + obj.name );
              console.log( 'address= ' + obj.address );
              console.log( 'sex= ' + obj.sex );
              console.log( 'mobile= ' + obj.mobile );
              console.log( 'qq= ' + obj.qq );
          };
          setUserInfo({
              id1314,
              name'sven',
              address'shenzhen',
              sex'male',
              mobile'137********',
              qq377876679
          });


          7. 少用三目運(yùn)算符

          三目運(yùn)算符性能高,代碼量少。

          但不應(yīng)該濫用三目運(yùn)算符,我們應(yīng)該在簡(jiǎn)單邏輯分支使用,在復(fù)雜邏輯分支避免使用。

          // 簡(jiǎn)單邏輯可以使用三目運(yùn)算符
          var global = typeof window !== "undefined" ? window : this;

          // 復(fù)雜邏輯不適合使用
          var ok = isString ? (isTooLang ? 2 : (isTooShort ? 1 : 0)) : -1;


          8. 合理使用鏈?zhǔn)秸{(diào)用

          優(yōu)點(diǎn): 鏈?zhǔn)秸{(diào)用使用簡(jiǎn)單,代碼量少。

          缺點(diǎn): 鏈?zhǔn)秸{(diào)用帶來的壞處就是在調(diào)試不方便,如果我們知道一條鏈中有錯(cuò)誤出現(xiàn),必須得先把這條鏈拆開才能加上一些調(diào)試 log 或者增加斷點(diǎn),這樣才能定位錯(cuò)誤出現(xiàn)的地方。

          如果該鏈條的結(jié)構(gòu)相對(duì)穩(wěn)定,后期不易發(fā)生修改,可以使用鏈?zhǔn)健?/p>

          var User = {
              idnull,
              namenull,
              setIdfunction( id ){
                  this.id = id;
                  return this;
              },
              setNamefunction( name ){
                  this.name = name;
                  return this;
              }
          };
          User
            .setId( 1314 )
            .setName( 'sven' );

          var user = new User();
          user.setId( 1314 );
          user.setName( 'sven' );


          9. 分解大型類

          大型類的分解和函數(shù)的提煉很像,類太大會(huì)出現(xiàn)邏輯不清晰,難以理解和維護(hù)的問題。

          合理的大類分解可以使類的邏輯清晰,且子模塊可以方便復(fù)用。

          10. 活用位操作符

          編程語言計(jì)算乘除的性能都不高,但是某些情況使用位操作符可以提升乘除等運(yùn)算的性能。

          11. 純函數(shù)

          純函數(shù)是指不依賴于不改變它作用域之外的變量狀態(tài)的函數(shù)。

          純函數(shù)的返回值只由它調(diào)用時(shí)的參數(shù)決定,它的執(zhí)行不依賴于系統(tǒng)的狀態(tài)(執(zhí)行上下文)。

          相同的輸入?yún)?shù),一定會(huì)得到相同的輸出,也就是內(nèi)部不含有會(huì)影響輸出的隨機(jī)變量。

          不屬于純函數(shù)的特點(diǎn):

          • 更改文件系統(tǒng)
          • 往數(shù)據(jù)庫插入記錄
          • 發(fā)送一個(gè) http 請(qǐng)求
          • 可變數(shù)據(jù)
          • 打印/log
          • 獲取用戶輸入
          • DOM 查詢
          • 訪問系統(tǒng)狀態(tài)

          純函數(shù)的作用:

          • 可靠性:函數(shù)返回永遠(yuǎn)和預(yù)期一致
          • 可緩存性:因?yàn)橹灰斎胍粯虞敵鲆欢ㄒ粯?,因此可將輸入作為key,輸出作為值,使用對(duì)象緩存已經(jīng)計(jì)算的結(jié)果
          • 可移植性:因?yàn)闆]有外部依賴,所以移植到任何環(huán)境都可正確運(yùn)行
          • 可測(cè)試性:方便針對(duì)函數(shù)做單元測(cè)試
          • 可并行性:對(duì)一些復(fù)雜計(jì)算,可以并行計(jì)算(例如使用nodejs多個(gè)子進(jìn)程同時(shí)并行計(jì)算多個(gè)任務(wù),提高計(jì)算速度)

          應(yīng)用場(chǎng)景:

          • 工具函數(shù)最好使用純函數(shù)
          • 多平臺(tái)使用的代碼(nodejs、瀏覽器、微信小程序、native客戶端等)
          • 相對(duì)獨(dú)立的功能
          var a = 1;
          // 非純函數(shù)
          function sum(b{
              return a + b;
          }
          // 非純函數(shù)
          function sum(b{
              a = 2;
              return b;
          }
          // 非純函數(shù)
          function sum(b{
              return b + Math.random();
          }


          // 純函數(shù)
          function sum (b, c{
              return b + c;
          }




          瀏覽 15
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产欧美在线视频 | 最新免费一区二区三区 | 超碰网站最新 | 大香蕉9| 91视频久久久久 |