大家都知道畅铭,所謂重載,就是一組相同的函數(shù)名其兴,有不同個數(shù)的參數(shù)顶瞒,在使用時調(diào)用一個函數(shù)名,傳入不同參數(shù)元旬,根據(jù)你的參數(shù)個數(shù)榴徐,來決定使用不同的函數(shù)!重載這個在JAVA這些經(jīng)典的編程語言里面都很好用匀归,可以說調(diào)用同一個方法名用不同的參數(shù)就可以為所欲為了坑资。
但是我們知道JavaScript中是沒有重載的(為什么沒重載?不是JAVA的特性JavaScript也會有的嗎穆端?)袱贮,因為后面定義的函數(shù)會覆蓋前面的同名函數(shù),但是重載那么好用体啰,我們想在JavaScript實現(xiàn)函數(shù)重載該怎么辦呢攒巍?
今天就來給大家講講在JavaScript里面實現(xiàn)函數(shù)重載的兩個思路。(零基礎的同學打擾了荒勇,這篇不太適合你柒莉,需要點面向對象基礎。)
第一種方法:
這種方法比較簡單沽翔,給一個思路兢孝,大家肯定都能理解,就是函數(shù)內(nèi)部用switch語句仅偎,根據(jù)傳入?yún)?shù)的個數(shù)調(diào)用不同的case語句跨蟹,從而功能上達到重載的效果。
這種方法簡單粗暴橘沥。但是對于一個正在學習js的人來說窗轩,這種方法未免太敷衍了。(那么沒技術含量座咆,怎么能讓我變成前端開發(fā)大神呢品姓?)
下面重點介紹一下第二種寝并,老實說我第一次看的時候很吃力,看了一個小時才捋清楚腹备,因為有的知識點雖然看過了但是不熟悉衬潦。(干貨很足,別看走神)
第二種方法:
我們這個例子植酥,是如果你不傳入?yún)?shù)镀岛,就會輸出所有的人,輸入firstname友驮,就會輸出匹配的人漂羊,如果輸入全名的人,也會輸出匹配的人卸留。如果用重載的話走越,用戶體驗確實會很好(這個例子是我以前學習時從網(wǎng)上扒下來的,很經(jīng)典耻瑟,具有代表性旨指,但是他們都沒有寫實現(xiàn)過程,所以今天我來給大家說講一下)
思路:這段代碼第一眼看的時候肯定是懵的喳整,再看一次好像有點思路谆构,再看就又懵了。
其實呢框都,這種方法巧妙的運用了JavaScript的閉包原理(重點)搬素,既然js后面的函數(shù)會覆蓋前面的同名函數(shù),我就強行讓所有的函數(shù)都留在內(nèi)存里魏保,等我需要的時候再去找它熬尺。
有了這個想法,是不是就想到了閉包谓罗,函數(shù)外訪問函數(shù)內(nèi)的變量猪杭,從而使函數(shù)留在內(nèi)存中不被刪除。這就是閉包的核心作用妥衣。
實現(xiàn)過程:
我們看一下上面這段代碼,最重要的是method方法的定義:這個方法中最重要的一點就是這個old戒傻,這個old真的很巧妙税手。它的作用相當于一個指針,指向上一次被調(diào)用的method函數(shù)需纳,這樣說可能有點不太懂芦倒,我們根據(jù)代碼來說,js的解析順序從上到下為不翩。
1.解析method(先不管里面的東西)
2.method(people,"find",function() ) 執(zhí)行這句的時候兵扬,它就回去執(zhí)行上面定義的方法麻裳,然后此時old的值為空,因為你還沒有定義過這個函數(shù)器钟,所以它此時是undefined津坑。
然后繼續(xù)執(zhí)行,這時候我們才定義 obj[name] = function()傲霸。
然后js解析的時候發(fā)現(xiàn)返回了fnc函數(shù)疆瑰,更重要的是fnc函數(shù)里面還調(diào)用了method里面的變量,這不就是閉包了昙啄!
因為fnc函數(shù)的實現(xiàn)是在調(diào)用時候才會去實現(xiàn)穆役,所以js就想,這我執(zhí)行完也不能刪除啊梳凛,要不外面那個用啥耿币,就留著吧先(此處用apply函數(shù)改變了fnc函數(shù)內(nèi)部的this指向)
3.好了第一次method的使用結束了,開始了第二句韧拒,method(people,"find",function(firstname) 然后這次使用的時候淹接,又要執(zhí)行old = obj[name]。
此時的old是什么叭莫,是函數(shù)了蹈集,因為上一條語句定義過了,而且沒有刪除雇初,那我這次的old實際上指向的是上次定義的方法拢肆,它起的作用好像一個指針,指向了上一次定義的 obj[name]靖诗。
然后繼續(xù)往下解析郭怪,又是閉包,還得留著刊橘。
4.第三句的method調(diào)用開始了鄙才,同理old指向的是上次定義的 obj[name] 同樣也還是閉包,還得留著促绵。
5.到這里攒庵,內(nèi)存中實際上有三個 obj[name],因為三次method的內(nèi)存都沒有刪除败晴,這是不是實現(xiàn)了三個函數(shù)共存浓冒,同時還可以用old將它們聯(lián)系起來是不是很巧妙
6.我們 people.find() 的時候,就會最先調(diào)用最后一次調(diào)用method時定義的function尖坤,如果參數(shù)個數(shù)相同 也就是 ?arguments.length === fnc.length 那么就執(zhí)行就好了稳懒,也不用找別的函數(shù)了,如果不相同的話慢味,那就得用到old了 ?return old.apply(this,arguments);
old指向的是上次method調(diào)用時定義的函數(shù)场梆,所以我們就去上一次的找墅冷,如果找到了,繼續(xù)執(zhí)行 arguments.length === fnc.length ?如果找不到或油,再次調(diào)用old 繼續(xù)向上找寞忿,只要你定義過,肯定能找到的装哆。
總結:運用閉包的原理使三個函數(shù)共存于內(nèi)存中罐脊,old相當于一個指針,指向上一次定義的function蜕琴,每次調(diào)用的時候萍桌,決定是否需要尋找。
最后來看看執(zhí)行輸出結果:
執(zhí)行過程很容易說明這一點:首先第一次調(diào)用的時候 old肯定不是函數(shù)凌简,所以instance判斷是false上炎,繼續(xù)調(diào)用的話就會為true。
然后雏搂,我們調(diào)用method的順序藕施,是從沒有參數(shù)到兩個參數(shù),所以我們最先調(diào)用find方法凸郑,是最后一次method調(diào)用時定義的裳食,所以fnc的length長度是2.然后向上找,length為1芙沥,最后終于找到了length為0的然后執(zhí)行诲祸,輸出。
好了而昨,今天的內(nèi)容就那么多吧救氯!要是你也喜歡,就轉發(fā)給更多朋友學習吧歌憨!
如果想學習更多前端開發(fā)教程着憨,歡迎關注公眾號【前端研究所】,每天更新更多新內(nèi)容哦务嫡!