不使用 JS 匿名函數(shù)理由
匿名函數(shù)的基本形式為(function(){...})();
前面的括號(hào)包含函數(shù)體,后面的括號(hào)就是給匿名函數(shù)傳遞參數(shù)并立即執(zhí)行之
匿名函數(shù)的作用是避免全局變量的污染以及函數(shù)名的沖突
無論你在什么時(shí)候讀代碼,您都必須注意到匿名函數(shù)。有時(shí)它們被稱為 lambda,有時(shí)是匿名函數(shù),不管怎樣,我認(rèn)為他們是不好使用的。
如果你不知道匿名函數(shù)是什么,這里有一個(gè)引語:
匿名函數(shù)是一種在運(yùn)行時(shí)動(dòng)態(tài)聲明的函數(shù)。它們之所以被稱為匿名函數(shù)是因?yàn)椴煌谄胀ê瘮?shù),它們并沒有函數(shù)名 。 — Helen Emerson, Helephant.com
匿名函數(shù)形式如下:
function () { ... code ... } OR (args) => { ... code .. }
我今天嘗試讓大家理解通常情況下只有在絕對(duì)需要的情況下才使用匿名函數(shù)的想法。匿名函數(shù)不應(yīng)該是首選,而且應(yīng)該知道原因情況下使用。當(dāng)理解這種想法之后,你的代碼會(huì)變得更簡(jiǎn)潔,更容易維護(hù),并且更容易跟蹤bug。先從避免使用匿名函數(shù)的三個(gè)理由開始:
你寫代碼的時(shí)候, 無論你多么擅長(zhǎng)敲代碼, 總是會(huì)碰到錯(cuò)誤。有時(shí)候,這些錯(cuò)誤很容易被查出,有時(shí)候并不容易。
如果你知道這些錯(cuò)誤來自哪里,那么錯(cuò)誤很容易會(huì)被查出來。為了查出錯(cuò)誤,我們使用這個(gè)被叫做堆棧軌跡的工具。如果你不了解 堆棧軌跡 ,goole給出了很棒的介紹。
假設(shè)現(xiàn)在有一個(gè)非常簡(jiǎn)單的工程:
function start () { (function middle () { (function end () { console.lg('test'); })() })() }
上面代碼里面有一個(gè)非常愚蠢的錯(cuò)誤,拼寫錯(cuò)誤(console.log)。在小工程里面,這個(gè)拼寫錯(cuò)誤不是什么大問題。 如果這是一個(gè)有非常多模塊非常大的工程的一小段,問題就大了。假設(shè)這個(gè)愚蠢的錯(cuò)誤不是你犯的,那么新來的初級(jí)工程師將會(huì)在他休假之前把這個(gè)錯(cuò)誤提交到代碼庫!
現(xiàn)在,我們必須追查。 使用我們精心命名的函數(shù), 我們得到如下的堆棧跟蹤:
謝謝你命名你的函數(shù) ,初級(jí)開發(fā)者們! 現(xiàn)在我們可以輕松地追蹤到這個(gè)bug。
但是..一旦我們解決了這個(gè)問題, 就會(huì)發(fā)現(xiàn) 還有另一個(gè)bug。 這次是一位更資深的開發(fā)人員介紹的。這個(gè)人知道 lambdas
結(jié)果他們偶然發(fā)現(xiàn)了一個(gè)bug,我們的工作就是追蹤它。
下面是代碼:
(function () { (function () { (function () { console.lg('test'); })(); })(); })();
吃不吃驚,這名開發(fā)者也忘記了如何拼寫console.log了!這也太巧合了吧!令人感到遺憾的是,他們都沒有命名他們的函數(shù)。
那么控制臺(tái)會(huì)輸出什么呢?
好吧,我們至少還有行號(hào),對(duì)吧?在這個(gè)例子中,看起來我們有大約7行代碼。如果我們處理一大段代碼會(huì)如何呢?比如一萬行代碼?行號(hào)的跨度如此之大該怎么辦呢?如果代碼被折疊后有沒有一個(gè)代碼地圖文件,那么對(duì)行號(hào)的渲染是不是根本就是沒有什么用了呢?
我想對(duì)這些問題的回答相當(dāng)簡(jiǎn)單,答案就是:想這些會(huì)讓你一整天都會(huì)過的相當(dāng)糟心。
可讀性
咦,我聽說你還不信。你仍舊對(duì)你的匿名函數(shù)戀戀不舍,并且還從未發(fā)生過bug。那么我得向你道歉,你認(rèn)為你的代碼是完美的。讓我們看看這個(gè)!
看看下面兩段代碼:
function initiate (arguments) { return new Promise((resolve, reject) => { try { if (arguments) { return resolve(true); } return resolve(false); } catch (e) { reject(e); } }); } initiate(true) .then(res => { if (res) { doSomethingElse(); } else { doSomething(); } ).catch(e => { logError(e.message); restartApp(); } );
這是一個(gè)非常不正常的例子,但是我相信你已經(jīng)明白我要說什么 了。我們的方法返回了一個(gè)promise,我們用這個(gè)promise對(duì)象/方法處理不同可能的 響應(yīng)。
你也許會(huì)認(rèn)為幾段代碼讀起來并不難,但我認(rèn)為它們可以變得更好!
如果我們?nèi)サ羲械哪涿瘮?shù)會(huì)怎樣呢?
function initiate (arguments) { return new Promise(checkForArguments); } function checkForArguments (resolve, reject) { try { if (arguments) { return resolve(true); } return resolve(false); } catch (e) { reject(e); } } function evaluateRes (res) { if (res) { doSomethingElse(); } else { doSomething(); } } function handleError (e) { logError(e.message); restartApp(); } initiate(true) .then(evaluateRes) .catch(handleError);
好,先講清楚:這部分代碼更長(zhǎng),但我認(rèn)為其不僅僅是有更多的可讀性!我們精心命名的函數(shù)與匿名函數(shù)不一樣,只要我們一看到它們的名字就知道它們的功能是什么。這避免了在評(píng)估代碼時(shí)的障礙。
這也有助于分清楚其中的關(guān)系。與創(chuàng)建一個(gè)方法、將其傳遞、然后運(yùn)行邏輯不同,在第二個(gè)例子中的參數(shù)被給到了then,catch只是指向了發(fā)生所有事情的函數(shù)。
關(guān)于更具有可讀性,我沒有什么再能說服你的了。但是也許你還沒被說服的話,我可以試一下最后的論據(jù)。
總結(jié)
以上所述是小編給大家介紹的不使用 JS 匿名函數(shù)的理由,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
js 通過html()及text()方法獲取并設(shè)置p標(biāo)簽的顯示值
這篇文章主要介紹了js 通過html()及text()方法獲取并設(shè)置p標(biāo)簽的顯示值,需要的朋友可以參考下2014-05-05JavaScript 核心參考教程 RegExp對(duì)象
JavaScript 核心參考教程RegExp對(duì)象,學(xué)習(xí)正則表達(dá)式的朋友可以參考下。2009-10-10electron實(shí)現(xiàn)讀取和寫入配置文件的示例詳解
這篇文章主要介紹了electron實(shí)現(xiàn)讀取和寫入配置文件的示例,文中通過代碼示例和圖文結(jié)合的方式介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03node.js+express+mySQL+ejs+bootstrop實(shí)現(xiàn)網(wǎng)站登錄注冊(cè)功能
這篇文章主要介紹了node.js+express+mySQL+ejs+bootstrop實(shí)現(xiàn)網(wǎng)站登錄注冊(cè)功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-01-01webpack配置文件外置的兩種實(shí)現(xiàn)方式
webpack配置環(huán)境變量文件,是根據(jù)打包命令尋找對(duì)應(yīng)的環(huán)境變量文件,從而獲取接口地址,本文就來介紹一下webpack配置文件外置的兩種實(shí)現(xiàn)方式,感興趣的可以了解一下2023-12-12js實(shí)現(xiàn)Form欄顯示全格式時(shí)間時(shí)鐘效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)Form欄顯示全格式時(shí)間時(shí)鐘效果代碼,可讀取當(dāng)前的完整時(shí)間并實(shí)時(shí)顯示,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-08-08ES6新特性之?dāng)?shù)組、Math和擴(kuò)展操作符用法示例
這篇文章主要介紹了ES6新特性之?dāng)?shù)組、Math和擴(kuò)展操作符用法,結(jié)合實(shí)例形式分析了ES6中數(shù)組、Math和擴(kuò)展操作符的新特性、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-04-04每天一篇javascript學(xué)習(xí)小結(jié)(Array數(shù)組)
這篇文章主要介紹了javascript中的Array數(shù)組知識(shí)點(diǎn),對(duì)數(shù)組的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下2015-11-11JS選中checkbox后獲取table內(nèi)一行TD所有數(shù)據(jù)的方法
這篇文章主要介紹了JS選中checkbox后獲取table內(nèi)一行TD所有數(shù)據(jù)的方法,涉及javascript針對(duì)table元素遍歷與獲取的技巧,需要的朋友可以參考下2015-07-07