亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實(shí)現(xiàn)函數(shù)重載的代碼示例

 更新時(shí)間:2023年08月22日 14:25:42   作者:閉目入神  
在JavaScript中并沒(méi)有直接支持函數(shù)重載的機(jī)制,但是可以通過(guò)一些技巧來(lái)模擬函數(shù)重載的效果,比如使用參數(shù)判斷,使用默認(rèn)參數(shù),對(duì)象參數(shù),這些方法都可以實(shí)現(xiàn)類(lèi)似函數(shù)重載的效果,所以本文就給大家介紹一下JavaScript如何實(shí)現(xiàn)函數(shù)重載,需要的朋友可以參考下

前言

今天開(kāi)發(fā)一個(gè)需求的時(shí)候,遇到了一個(gè)類(lèi)似函數(shù)重載的場(chǎng)景。

這個(gè)需求可以接收一個(gè)下標(biāo)。

當(dāng)下標(biāo)存在時(shí),執(zhí)行邏輯A。
當(dāng)下標(biāo)不存在時(shí),執(zhí)行邏輯B。

看著很簡(jiǎn)單對(duì)吧。

if(index === undefined) {
    A()
} else {
    B()
}

直接一個(gè)if else解決,但是我們可以換種思路,通過(guò)函數(shù)重載的方式去實(shí)現(xiàn)它,后續(xù)如果參數(shù)格式繼續(xù)變化,其拓展性也會(huì)更好。

因此就打算實(shí)現(xiàn)一個(gè)函數(shù),通過(guò)js實(shí)現(xiàn)函數(shù)重載的能力。

知識(shí)鋪墊

在實(shí)現(xiàn)函數(shù)重載之前,先回顧下什么是函數(shù)重載?
學(xué)過(guò)java的朋友當(dāng)然很熟悉,但學(xué)習(xí)前端的同學(xué)可能就不太熟悉了,因?yàn)?code>js并不支持函數(shù)重載。

什么是函數(shù)重載呢?

簡(jiǎn)單來(lái)說(shuō)就是 同一個(gè)作用域內(nèi)定義多個(gè)同名函數(shù)但參數(shù)個(gè)數(shù)或類(lèi)型不同的情況。針對(duì)不同的參數(shù)可以定義不同的函數(shù)邏輯,比如:

public class OverloadingExample {
    // 函數(shù)重載:整數(shù)相加
    public int add(int a, int b) {
        return a + b + 1;
    }
    // 函數(shù)重載:浮點(diǎn)數(shù)相加
    public double add(double a, double b) {
        return a + b;
    }
    public static void main(String[] args) {
        OverloadingExample example = new OverloadingExample();
        System.out.println("Sum of integers: " + example.add(2, 3));
        System.out.println("Sum of doubles: " + example.add(2.5, 3.5));
    }
}

這里的add函數(shù)是存在同名的,但是二者類(lèi)型不同,會(huì)去執(zhí)行不同的代碼。

那對(duì)于我們常用的js而言,函數(shù)重載是不支持的。

所以我們一般會(huì)采用條件判斷或者對(duì)象參數(shù)這種方式實(shí)現(xiàn):

// 條件判斷
function exampleFunction(param1, param2 = null) {
  if (param2 === null) {
    // 處理只有一個(gè)參數(shù)的情況
  } else {
    // 處理兩個(gè)參數(shù)的情況
  }
}
// 參數(shù)對(duì)象
function exampleFunction(options) {
  if (object.keys(options).length == 1) {
    // 處理只有一個(gè)參數(shù)的情況
  } else {
    // 處理多個(gè)參數(shù)的情況
  }
}
// 函數(shù)名稱區(qū)分
function exampleFunctionOneParams(param) {
  // 處理只有一個(gè)參數(shù)的情況
}
function exampleFunctionTwoParams(param1, param2) {
  // 處理只有兩個(gè)參數(shù)的情況
}

代碼思路

首先在上面的知識(shí)鋪墊中,我們知道函數(shù)重載的核心是定義多個(gè)同名函數(shù),通過(guò)不同的參數(shù)類(lèi)型或組合執(zhí)行不同的代碼。

思路如下:

1.可以維護(hù)一個(gè)類(lèi),在類(lèi)中???一個(gè)對(duì)象,對(duì)象中函數(shù)名做key,value是一個(gè)新的對(duì)象。2.其中新的對(duì)象中 又以不同參數(shù)類(lèi)型組合而成字符串作為key,而對(duì)應(yīng)函數(shù)為value。3.使用時(shí)先實(shí)例化class。4.將目標(biāo)函數(shù)這個(gè)目標(biāo)函數(shù)的參數(shù)集合傳入,實(shí)例化對(duì)象中新增和目標(biāo)函數(shù)同名的函數(shù),并將目標(biāo)函數(shù)和參數(shù)集合注冊(cè)到映射對(duì)象中。4.使用時(shí),直接調(diào)用實(shí)例對(duì)象下的目標(biāo)函數(shù),由目標(biāo)函數(shù)提供的同名函數(shù)去映射到對(duì)應(yīng)的map中注冊(cè)的真實(shí)函數(shù)并執(zhí)行。

代碼實(shí)現(xiàn)

// 非法賦值標(biāo)識(shí)
let isAssignmentValid = false
class Overload {
  constructor() {
    this.fnMap = new Proxy({}, {
      set: setProxyValid
    });
    return new Proxy(this, {
      set: setProxyValid
    });
  }
  // 重載函數(shù)注冊(cè)
  reg(fn, arr = []) {
    // 注冊(cè)函數(shù)映射map
    if(typeof fn !== 'function') throw new Error(`params err`);
    isAssignmentValid = true
    const typesKey = arr.join('_');
    if (!this.fnMap[fn.name]) {
      this.fnMap[fn.name] = new Proxy({}, {
        set: setProxyValid
      });
    }
    this.fnMap[fn.name][typesKey] = fn;
    // 注冊(cè)重載實(shí)例同名函數(shù)
    if (!this[fn.name]) {
      this[fn.name] = (...args) => {
          const typesKey = getParameterTypesKey(...args);
          const targetFn = this.fnMap[fn.name][typesKey];
          return targetFn(...args);
        }
    }
    isAssignmentValid = false
  }
}
// proxy 禁止非法賦值 封裝
function setProxyValid(target, property, value) {
  if(isAssignmentValid) {
    target[property] = value
    return true
  } else {
    throw new Error(`Cannot set attribute`);
  }
}
// 獲取參數(shù)類(lèi)型key
function getParameterTypesKey(...args) {
  const parameterTypes = args.map(arg => typeof arg);
  const parameterTypesKey = parameterTypes.join('_');
  return parameterTypesKey;
}
// 導(dǎo)出工廠函數(shù)
export function OverloadFactory() {
  return new OverloadJS()
}

代碼解釋

這段代碼是一個(gè) JavaScript 的重載函數(shù)。
它允許你定義同名函數(shù)但參數(shù)不同的多個(gè)版本,然后根據(jù)傳入的參數(shù)類(lèi)型來(lái)自動(dòng)調(diào)用對(duì)應(yīng)的函數(shù)版本。

步驟一

代碼先定義了一個(gè) isAssignmentValid 標(biāo)識(shí),表示當(dāng)前能否對(duì)重載實(shí)例或類(lèi)進(jìn)行賦值

步驟二

代碼的構(gòu)造函數(shù)中會(huì)創(chuàng)建一個(gè)proxy對(duì)象 fnMap,這個(gè)對(duì)象的作用是存儲(chǔ)函數(shù)和參數(shù)集合間的映射關(guān)系。
構(gòu)造函數(shù)最后會(huì)返回一個(gè)指向this對(duì)proxy對(duì)象,后續(xù)的注冊(cè)和函數(shù)調(diào)用都會(huì)在這個(gè)proxy實(shí)例上進(jìn)行。注:(代碼中所有的proxy對(duì)象,會(huì)使用 setProxyValid 函數(shù)對(duì)set操作進(jìn)行封裝,禁止非法賦值,防止開(kāi)發(fā)時(shí)開(kāi)發(fā)人員誤賦值,導(dǎo)致重載實(shí)例異常。)

步驟三

代碼中的reg是重載函數(shù)的注冊(cè)函數(shù)也是核心方法。
主要分成兩部分

PART1: (注冊(cè)函數(shù)映射map)

注冊(cè)函數(shù)接受兩個(gè)參數(shù)一個(gè)是需要重載的目標(biāo)函數(shù),一個(gè)是目標(biāo)函數(shù)接受的參數(shù)類(lèi)型數(shù)組。

首先,代碼使用 typeof 運(yùn)算符判斷傳入的 fn 是否為一個(gè)函數(shù),如果不是,則拋出一個(gè)錯(cuò)誤,提示參數(shù)錯(cuò)誤。

接下來(lái),將 isAssignmentValid 標(biāo)志設(shè)置為 true ,表示當(dāng)前處于合法賦值狀態(tài)。這是為了在注冊(cè)函數(shù)時(shí)允許對(duì) fnMap 進(jìn)行賦值操作。

然后,通過(guò)將參數(shù)數(shù)組 arr 使用 _ 連接起來(lái),生成一個(gè)用于標(biāo)識(shí)參數(shù)類(lèi)型的 key,賦值給變量 typesKey

接著,通過(guò)檢查 fnMap 中是否存在以 fn.name 為鍵的屬性,來(lái)判斷是否已經(jīng)注冊(cè)過(guò)該函數(shù)。如果不存在,則創(chuàng)建一個(gè)新的 Proxy 對(duì)象,并將其賦值給 fnMap 中以 fn.name 為鍵的屬性。這個(gè) Proxy 對(duì)象的作用是攔截對(duì)屬性的賦值操作,以控制賦值的合法性。

最后,將函數(shù) fn 存儲(chǔ)到 fnMap[fn.name][typesKey] 的位置,以完成函數(shù)的注冊(cè)和存儲(chǔ)。

這段代碼的作用是在注冊(cè)函數(shù)時(shí),將函數(shù)和對(duì)應(yīng)的參數(shù)類(lèi)型映射存儲(chǔ)起來(lái),以便后續(xù)根據(jù)傳入的參數(shù)類(lèi)型選擇正確的函數(shù)版本進(jìn)行調(diào)用。

PART2:(注冊(cè)重載實(shí)例同名函數(shù))

這段代碼的作用是在注冊(cè)函數(shù)時(shí),為重載實(shí)例創(chuàng)建同名函數(shù)。

首先,代碼判斷當(dāng)前實(shí)例對(duì)象中是否已經(jīng)存在同名函數(shù) fn.name 。如果不存在,則進(jìn)入條件語(yǔ)句塊。

在條件語(yǔ)句塊中,代碼定義了一個(gè)箭頭函數(shù),并將其賦值給實(shí)例對(duì)象的同名屬性 this[fn.name] 。這個(gè)箭頭函數(shù)接受任意數(shù)量的參數(shù) ...args 。

在箭頭函數(shù)內(nèi)部,首先調(diào)用 getParameterTypesKey 函數(shù),傳入?yún)?shù) ...args ,獲取參數(shù)類(lèi)型的 key,并將其賦值給變量 typesKey

接下來(lái),通過(guò)訪問(wèn) fnMap 屬性,獲取存儲(chǔ)在 fnMap[fn.name][typesKey] 位置的目標(biāo)函數(shù),并將其賦值給變量 targetFn 。

最后,箭頭函數(shù)調(diào)用 targetFn ,并傳入?yún)?shù) ...args ,返回函數(shù)調(diào)用的結(jié)果。 最后一行代碼將 isAssignmentValid 標(biāo)志設(shè)置為 false ,表示結(jié)束合法賦值狀態(tài)。

這段代碼的作用是為重載實(shí)例創(chuàng)建同名函數(shù),這些同名函數(shù)會(huì)根據(jù)傳入的參數(shù)類(lèi)型選擇對(duì)應(yīng)的函數(shù)版本進(jìn)行調(diào)用。這樣,在調(diào)用重載函數(shù)時(shí),可以直接通過(guò)實(shí)例對(duì)象的同名屬性來(lái)調(diào)用對(duì)應(yīng)的函數(shù)版本。

步驟四

最后導(dǎo)出工廠函數(shù),提供業(yè)務(wù)側(cè)使用。

基礎(chǔ)使用

創(chuàng)建重載實(shí)例

const OverloadInstance = OverloadFactory() // 創(chuàng)建重載實(shí)例

注冊(cè)同名函數(shù)

OverloadInstance.reg(function exampleFn(param1, param2) { //注冊(cè)同名函數(shù)
    // 函數(shù)邏輯
}, ['number', 'string'])
OverloadInstance.reg(function exampleFn(param1) {
    // 函數(shù)邏輯
}, ['number'])

調(diào)用重載函數(shù)

OverloadInstance.exampleFn(20, 'hello world') // 調(diào)用重載函數(shù)
OverloadInstance.exampleFn(20)

代碼用例

簡(jiǎn)單用例:

let x = OverloadFactory() // 創(chuàng)建重載實(shí)例
x.reg(function name(a) { // 注冊(cè)同名函數(shù)
  console.log(a)
}, ['number'])
x.reg(function name(a, b) {
  console.log(a + b)
}, ['number', 'number'])
x.reg(function text(a) {
  console.log(a)
}, ['string'])
x.reg(function text(a, b) {
  console.log(a + b)
}, ['string', 'number'])
x.name(20, 10) // 函數(shù)調(diào)用
x.name(20)
x.text('hello', 10)
x.text('hello')

運(yùn)行結(jié)果:

代碼缺陷

1.getParameterTypesKey 函數(shù)的類(lèi)型判斷太簡(jiǎn)單。2.重載實(shí)例取空值異常處理缺失

總結(jié)

這段代碼實(shí)現(xiàn)了一個(gè)重載函數(shù)庫(kù),它允許你定義同名函數(shù)但參數(shù)不同的多個(gè)版本,并根據(jù)傳入的參數(shù)類(lèi)型自動(dòng)選擇調(diào)用對(duì)應(yīng)的函數(shù)版本。

以上就是JavaScript實(shí)現(xiàn)函數(shù)重載的代碼示例的詳細(xì)內(nèi)容,更多關(guān)于JavaScript實(shí)現(xiàn)函數(shù)重載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁(yè)數(shù)字鍵盤(pán)

    Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁(yè)數(shù)字鍵盤(pán)

    這篇文章主要為大家詳細(xì)介紹了Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁(yè)數(shù)字鍵盤(pán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • javascript每日必學(xué)之循環(huán)

    javascript每日必學(xué)之循環(huán)

    javascript每日必學(xué)之循環(huán),本文的主要內(nèi)容就是循環(huán),死循環(huán)時(shí)進(jìn)行bug調(diào)式,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 基于js實(shí)現(xiàn)的限制文本框只可以輸入數(shù)字

    基于js實(shí)現(xiàn)的限制文本框只可以輸入數(shù)字

    本文主要介紹了js限制文本框只可以輸入數(shù)字的實(shí)例代碼,可復(fù)制直接調(diào)用函數(shù)實(shí)現(xiàn)其功能。需要的朋友可以看下
    2016-12-12
  • JS打斷點(diǎn)的六種常用姿勢(shì)你用過(guò)幾種

    JS打斷點(diǎn)的六種常用姿勢(shì)你用過(guò)幾種

    JS斷點(diǎn)調(diào)試,即是在瀏覽器開(kāi)發(fā)者工具中為JS代碼添加斷點(diǎn),讓JS執(zhí)行到某一特定位置停住,方便開(kāi)發(fā)者對(duì)該處代碼段的分析,這篇文章主要介紹了JS打斷點(diǎn)的六種常用姿勢(shì)的相關(guān)資料,需要的朋友可以參考下
    2025-04-04
  • html5 canvas js(數(shù)字時(shí)鐘)實(shí)例代碼

    html5 canvas js(數(shù)字時(shí)鐘)實(shí)例代碼

    這篇文章主要介紹了html5 canvas js(數(shù)字時(shí)鐘)實(shí)例代碼,有需要的朋友可以參考一下
    2013-12-12
  • JS生成登錄驗(yàn)證碼的實(shí)現(xiàn)示例

    JS生成登錄驗(yàn)證碼的實(shí)現(xiàn)示例

    本文主要介紹了JS生成登錄驗(yàn)證碼的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • 微信小程序如何自定義table組件

    微信小程序如何自定義table組件

    這篇文章主要介紹了微信小程序如何自定義table組件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-06-06
  • javascript實(shí)現(xiàn)表單隔行變色

    javascript實(shí)現(xiàn)表單隔行變色

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)表單隔行變色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 微信小程序點(diǎn)擊左上角返回彈窗提示解決思路

    微信小程序點(diǎn)擊左上角返回彈窗提示解決思路

    當(dāng)頁(yè)面表單沒(méi)有提交直接返回時(shí),要提示用戶是否保存當(dāng)前信息,如果已經(jīng)提交就不提示了,下面小編給大家?guī)?lái)了微信小程序點(diǎn)擊左上角返回彈窗提示解決思路,感興趣的朋友一起看看吧
    2024-06-06
  • IE8 下的Js錯(cuò)誤HTML Parsing Error...

    IE8 下的Js錯(cuò)誤HTML Parsing Error...

    今天調(diào)試一段JS代碼出現(xiàn)這個(gè)狀況..在火狐 IE7 和IE6下都正常...郁悶,在網(wǎng)上搜索了一下相關(guān)資料 一般錯(cuò)誤都是指所指定的標(biāo)簽沒(méi)有加載完就是用該對(duì)象....
    2009-08-08

最新評(píng)論