成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

不使用JS匿名函數的三個理由

開發 前端
無論你在什么時候讀代碼,您都必須注意到匿名函數。有時它們被稱為 lambda,有時是匿名函數,不管怎樣,我認為他們是不好使用的。

無論你在什么時候讀代碼,您都必須注意到匿名函數。有時它們被稱為 lambda,有時是匿名函數,不管怎樣,我認為他們是不好使用的。

[[214508]]

如果你不知道匿名函數是什么,這里有一個引語:

匿名函數是一種在運行時動態聲明的函數。它們之所以被稱為匿名函數是因為不同于普通函數,它們并沒有函數名。 — Helen Emerson, Helephant.com

匿名函數形式如下:

  1. function () { ... code ... } 
  2. OR 
  3. (args) => { ... code .. } 

今天我嘗試讓大家理解只有在絕對需要的情況下才使用匿名函數的想法。匿名函數不應該是***,而且你自己也應該知道為什么使用它。當理解這種想法之后,你的代碼會變得更簡潔,更容易維護,并且更容易跟蹤bug。

先從避免使用匿名函數的三個理由開始:

無論你多么擅長寫代碼,出現錯誤也是不可避免的。有時候,這些錯誤很容易被查出,有時候并不容易。

如果你知道這些錯誤來自哪里,那么錯誤會很容易被查出來。為了容易查出錯誤,我們使用這個被叫做堆棧軌跡的工具。如果你不了解堆棧軌跡,goole給出了很棒的介紹。

假設現在有一個非常簡單的項目: 

  1. function start () { 
  2.  (function middle () { 
  3.    (function end () { 
  4.      console.lg('test'); 
  5.     })() 
  6.   })() 

上面代碼里面有一個非常愚蠢的錯誤,拼寫錯誤(console.log)。在小項目里面,這個拼寫錯誤不是什么大問題。如果這是一個有非常多模塊非常大的項目一小段,問題就大了。假設這個愚蠢的錯誤不是你犯的,那么新來的初級工程師將會在他休假之前把這個錯誤提交到代碼庫!

現在,我們必須追查。 使用我們精心命名的函數,我們得到如下的堆棧跟蹤:

謝謝你命名你的函數,初級開發者們! 現在我們可以輕松地追蹤到這個bug。

但是..一旦我們解決了這個問題,就會發現還有另一個bug。 這次是一位更資深的開發人員介紹的。這個人知道lambdas(匿名函數),并在代碼中大量使用它們。 結果他們偶然發現了一個bug,我們的工作就是追蹤它。

下面是代碼: 

  1. (function () { 
  2.  (function () { 
  3.    (function () { 
  4.      console.lg('test'); 
  5.     })(); 
  6.   })(); 
  7. })(); 

吃不吃驚,這名開發者也忘記了如何拼寫console.log了!這也太巧合了吧!令人感到遺憾的是,他們都沒有命名他們的函數。

那么控制臺會輸出什么呢? 

好吧,我們至少還有行號,對吧?在這個例子中,看起來我們有大約7行代碼。如果我們處理一大段代碼會如何呢?比如一萬行代碼?行號的跨度如此之大該怎么辦呢?如果代碼被折疊后有沒有一個代碼地圖文件,那么對行號的渲染是不是根本就是沒有什么用了呢?

我想對這些問題的回答相當簡單,答案就是:想這些會讓你一整天都會過的相當糟心。

可讀性

咦,我聽說你還不信。你仍舊對你的匿名函數戀戀不舍,并且還從未發生過bug。我的錯,你的代碼是完整的。但是讓我們看看這個! 

看看下面兩段代碼: 

  1. function initiate (arguments) { 
  2.   return new Promise((resolve, reject) => { 
  3.     try { 
  4.       if (arguments) { 
  5.          return resolve(true); 
  6.       } 
  7.       return resolve(false); 
  8.     } catch (e) { 
  9.       reject(e); 
  10.     } 
  11.   }); 
  12.  
  13. initiate(true
  14.   .then(res => { 
  15.         if (res) { 
  16.           doSomethingElse(); 
  17.         } else { 
  18.           doSomething(); 
  19.         } 
  20.   ).catch(e => { 
  21.             logError(e.message); 
  22.             restartApp(); 
  23.           } 
  24.   ); 

這是一個非常不正常的例子,但是我相信你已經明白我要說什么了。我們反悔了一個promise方法,我們用這個promise對象/方法處理不同的響應。

你也許會認為幾段代碼讀起來并不難,但我認為它們可以變得更好! 

如果我們去掉所有的匿名函數會怎樣呢? 

  1. function initiate (arguments) { 
  2.   return new Promise(checkForArguments); 
  3.  
  4. function checkForArguments (resolve, reject) { 
  5.   try { 
  6.     if (arguments) { 
  7.      return resolve(true);    
  8.     } 
  9.     return resolve(false); 
  10.   } catch (e) { 
  11.     reject(e); 
  12.   } 
  13.  
  14. function evaluateRes (res) { 
  15.   if (res) { 
  16.     doSomethingElse(); 
  17.   } else { 
  18.     doSomething(); 
  19.   } 
  20.  
  21. function handleError (e) { 
  22.   logError(e.message); 
  23.   restartApp(); 
  24.  
  25. initiate(true
  26.   .then(evaluateRes) 
  27.   .catch(handleError); 

好,先講清楚:這部分代碼更長,但我不認為只是增加了可讀性!我們精心命名的函數與匿名函數不一樣,只要我們一看到它們的名字就知道它們的功能是什么。這避免了在評估代碼時出現心理障礙。

這也有助于分清楚其中的關系。與創建一個方法、將其傳遞、然后運行邏輯不同,在第二個例子中的參數被給到了then,catch只是指向了發生所有事情的函數。

關于更具有可讀性,我沒有什么再能說服你的了。但是也許你還沒被說服的話,我可以試一下***的論據。

可重用性

你注意到上一個例子了嗎?上個例子中的函數的使用范圍從參數和初始化函數,變為讓所有函數都能使用。

當你使用匿名函數時這些函數很難在你的應用程序內重復使用。

可重用性將不復存在,最終你會一遍又一遍地寫重復的代碼。正如我們所見的,代碼寫的越少引入的Bug就越少,用戶必須加載的內容就越少。所有人都會因此獲益!

相反的,命名函數可以全局使用,而不需要像變量一樣到處傳遞。你的代碼的可重用性會更好, 

匿名函數有可取的地方嗎?

有。雖然很不愿意承認,但有時候使用匿名函數是***的選擇。 

  1. const stuff = [  
  2.   { hide: truename'justin' },  
  3.   { hide: falsename'lauren' }, 
  4.   { hide: falsename'max' }, 
  5. ]; 
  6. const filteredStuff = stuff.filter(s => !s.hide); 

上邊代碼中的匿名函數s => !s.hide非常簡單,即使不能在別的地方使用也不會對別人有任何影響,而且也可以在stuff.filter中顯示出堆棧調用。如果想要重用這段代碼,***重用整段代碼: 

  1. function filterByHide (array) { 
  2.   return array.filter(item => !item.hide); 

有時你想把你所有的代碼封裝到匿名函數中,以保證全局范圍不會被污染。 

  1. (() => { 
  2.  ... your code here ... 
  3. })(); 

在棧空間中擁有一個***的匿名函數真得不會有什么錯誤。沒有代碼重用是痛苦的,因為完整的目的是保持方法內含。

我確定這會有其他好的用法,請在評論中自由分享之!

感謝閱讀,現在跳出這些,并停止編寫匿名函數!

責任編輯:未麗燕 來源: 開源中國翻譯
相關推薦

2012-11-21 10:01:35

RubyWeb

2021-11-17 10:38:22

邊緣計算云端

2021-06-16 12:53:57

Java編程語言

2013-12-09 09:54:58

2015-12-11 15:52:47

盛大云

2020-03-07 15:25:38

TypeScript代碼開發

2010-05-13 11:45:56

MySQL數據庫

2021-01-04 20:48:19

TypeScriptJS前端

2010-06-10 10:50:17

MySQL數據庫

2011-05-18 15:40:52

MySQL

2020-01-03 16:16:15

云計算技術工具

2011-03-02 13:54:39

MySQL數據庫

2021-06-11 17:49:29

變量代碼計算機

2009-08-08 08:47:07

Windows 7新特性

2009-09-10 08:32:14

Windows 7企業升級寶馬

2020-01-10 11:13:23

人工智能大數據IT

2013-04-01 09:20:05

JavaScript

2015-06-23 09:10:04

Spark主機托管云平臺

2023-04-26 11:14:11

IT領導者遠程工作

2009-08-06 11:00:19

C#對象的使用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久一区探花 | 久久夜视频| 国产视频久久久 | 国产日韩精品在线 | 亚洲精品日韩在线观看 | 国产视频精品免费 | 爱操影视| 欧美一区二区三区视频 | 特黄一级 | 免费久 | 欧美精品一区二区三区在线播放 | 人人爽人人爽 | 五月婷婷婷 | 一区二区在线视频 | 亚洲一二三区不卡 | 久久久久久久久国产精品 | 成人三级av | 久久婷婷色 | 精品一区二区三区中文字幕 | 成人免费小视频 | 久久综合伊人一区二区三 | 一级做a爰片性色毛片16 | 成人国产免费视频 | 国产精品96久久久久久 | 国产精品成人久久久久 | 天天插天天操 | 亚洲视频一区在线观看 | 人人艹人人爽 | 日本精品一区二区 | 综合视频在线 | 亚洲免费在线视频 | 91麻豆精品国产91久久久更新资源速度超快 | 欧美日韩精品免费 | 亚洲黄色一区二区三区 | 久久久久久久久久久久91 | 国产精品日本一区二区在线播放 | 欧美日韩综合一区 | 成人aaa视频| 玖玖久久| 天堂在线免费视频 | 免费国产黄网站在线观看视频 |