欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何通過JavaScript實現(xiàn)函數(shù)重載

 更新時間:2023年01月12日 08:40:37   作者:JiangHong  
這篇文章主要為大家詳細介紹了如何通過JavaScript實現(xiàn)函數(shù)重載,文中的示例代碼講解詳細,對我們學(xué)習(xí)JavaScript有一定的幫助,感興趣的可以了解一下

有的同學(xué)在開發(fā)中可能遇到過一個困擾,但是很少有人去解決這個問題,我這用一個例子展現(xiàn)出來

const searcher = {};
searcher.findAll = () => {
  console.log("查詢所有用戶");
};
searcher.findByName = (name) => {
  console.log("按照用戶名稱查詢");
};
searcher.findByFirstNameAndLastName = (firstName, lastName) => {
  console.log("按照姓和名用戶查詢");
};

可以看到上方的searcher對象有三個方法,但是他的查詢邏輯是不一樣。 findAll查詢所有用戶;findByName按照用戶名查;findByFirstNameAndLastName是按照姓和名查詢用戶,結(jié)構(gòu)上沒任何問題,那問題在哪?,惡心因為都是在做查詢,但又不得不給每一個函數(shù)取不同的名字,因為一旦重名就覆蓋了,如果說他們能取一樣的名字那該有多好

searcher.find = () => {
  console.log("查詢所有用戶");
};
searcher.find = (name) => {
  console.log("按照用戶名稱查詢");
};
searcher.find = (firstName, lastName) => {
  console.log("按照姓和名用戶查詢");
};

不傳參數(shù)就是查所有用戶

searcher.find()

給一個參數(shù)就是按照用戶名來查詢

searcher.find("aa")

給兩個參數(shù)就是按照用戶的姓跟名來查詢

searcher.find("aa", "bb")

到用得時候也是非常的簡單,也符合邏邏輯,這個就叫做函數(shù)重載

函數(shù)重載:就是給函數(shù)取同一樣的一個函數(shù)名,根據(jù)你傳遞不同的參數(shù)數(shù)量,分別去調(diào)用不同的函數(shù)

好處:就在于使用不同的邏輯產(chǎn)生的函數(shù),給他們?nèi)∫粋€相同的名字,這樣在使用上我只需要記住這個一樣的名字就可以了,而不用去記這三個不同的名字,他有效的降低調(diào)用函數(shù)時產(chǎn)生的心智負擔(dān)。

但是JS不支持函數(shù)重載,所以說如果你寫成已上的形式,無論你怎么調(diào)用,一定是調(diào)用最后一個函數(shù),因為最后一個函數(shù)把前面的全部覆蓋了
不傳參數(shù)試一下,你看永遠都是走最后一個函數(shù)的log

    searcher.find() // 按照姓和名用戶查詢

那有什么辦法呢?在很早的時候jQuery之父John Resig 他就已經(jīng)提出了一個想法,我們能不能實現(xiàn)一個方法來幫助我們在js中完成函數(shù)重載?

于是他想出了一個addMethod方法,就是當我要重載的時,我不直接去定義函數(shù),因為直接定義函數(shù)就會出現(xiàn)一個永遠只調(diào)用最后一個函數(shù)的問題,而調(diào)用addMethod來定義函數(shù),把對象傳進去,把函數(shù)的名字傳進去,把函數(shù)的實現(xiàn)傳進去,后面依次同理

addMethod(searcher, 'find', () => {
    console.log('查詢所有用戶')
})
addMethod(searcher, 'find', (name) => {
    console.log('按照用戶名稱查詢')
})
addMethod(searcher, 'find', (firstName, lastName) => {
    console.log('按照姓和名用戶查詢')
})

寫成這種格式之后,后面調(diào)用searcher.find()就能夠完成函數(shù)重載,問題是這個方法我們得要自己實現(xiàn),那么如何來實現(xiàn)? 這個方法他接受三個參數(shù),如果你不加處理的話你可能寫成下面函數(shù)一樣,給對象加一個屬性,這個屬性等于一個函數(shù),調(diào)用這個函數(shù)實際上就是在運行定義的實現(xiàn)函數(shù)fn,把this綁定帶過去 然后把傳遞過來的arguments帶過去

function addMethod(object, name, fn) {
  object[name] = function () {
      fn.apply(this, arguments)
  }
}

僅僅這么些還是搞不定,因為每次調(diào)用addMethod最后一次調(diào)用一定會把object里面同一個屬性給覆蓋掉,那么如何處理?看下方代碼

function addMethod(object, name, fn) {
  const old = object[name];
  object[name] = function () {
    if (arguments.length === fn.length) {
      fn.apply(this, arguments);
    } else if (typeof old === "function") {
      old.apply(this, arguments);
    }
  };
}

首先我不傳參數(shù)走查詢所有用戶,傳一個參數(shù)走按照用戶名查詢,傳兩個參數(shù)按照姓和名查詢

直接看方法體有的同學(xué)可能不理解其中的巧妙,我來研究一下這個方法并記錄一下執(zhí)行規(guī)則

第一次調(diào)用: 通過 old 變量首先保存了之前成員的值,當然這一次保存由于是第一次調(diào)用,所以他是一個undefined 然后給object[name]賦值了一個新的函數(shù),這個函數(shù)在運行的時候做了一個判斷,當你傳遞的實參數(shù)量與你定義函數(shù)形參數(shù)量一致的時候就執(zhí)行該函數(shù)由此可得:

第二次調(diào)用:關(guān)鍵是否則,判斷一下old是否是函數(shù),如果是那調(diào)用old就會執(zhí)行上面第一次得出的邏輯,同理可得:

第三次調(diào)用:同理可得:

以上是一個注冊的順序,當我們調(diào)用時傳遞0個參數(shù),他會從最后一個開始執(zhí)行,當形參數(shù)量相等就會直接執(zhí)行當前的方法,如果不相等就會執(zhí)行old也就是上一個find的邏輯,類似于冒泡執(zhí)行,等到執(zhí)行到第一次注冊的邏輯判斷時形參數(shù)量相等了,就直接執(zhí)行第一次注冊的方法,執(zhí)行打印 "查詢所有用戶"

searcher.find() // 查詢所有用戶

總結(jié)

其實就是用到了閉包,將閉包形成了閉包鏈把我們傳遞的方法依次注冊。在調(diào)用的時候從最后一個有序的去找,用這種非常巧妙的方式,用極少的代碼就實現(xiàn)了一個函數(shù)重載的效果,函數(shù)重載雖然說你不一定能用到,但是通過去解析這個addMethod,我們可以感受到有這么智慧的實現(xiàn)方案,肯定對你將來實現(xiàn)某一些東西的時候,有所啟發(fā)。

到此這篇關(guān)于詳解如何通過JavaScript實現(xiàn)函數(shù)重載的文章就介紹到這了,更多相關(guān)JavaScript函數(shù)重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論