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

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

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

前言

今天開發(fā)一個需求的時候,遇到了一個類似函數(shù)重載的場景。

這個需求可以接收一個下標。

當下標存在時,執(zhí)行邏輯A。
當下標不存在時,執(zhí)行邏輯B。

看著很簡單對吧。

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

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

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

知識鋪墊

在實現(xiàn)函數(shù)重載之前,先回顧下什么是函數(shù)重載?
學過java的朋友當然很熟悉,但學習前端的同學可能就不太熟悉了,因為js并不支持函數(shù)重載

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

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

public class OverloadingExample {
    // 函數(shù)重載:整數(shù)相加
    public int add(int a, int b) {
        return a + b + 1;
    }
    // 函數(shù)重載:浮點數(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ù)是存在同名的,但是二者類型不同,會去執(zhí)行不同的代碼。

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

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

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

代碼思路

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

思路如下:

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

代碼實現(xiàn)

// 非法賦值標識
let isAssignmentValid = false
class Overload {
  constructor() {
    this.fnMap = new Proxy({}, {
      set: setProxyValid
    });
    return new Proxy(this, {
      set: setProxyValid
    });
  }
  // 重載函數(shù)注冊
  reg(fn, arr = []) {
    // 注冊函數(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;
    // 注冊重載實例同名函數(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ù)類型key
function getParameterTypesKey(...args) {
  const parameterTypes = args.map(arg => typeof arg);
  const parameterTypesKey = parameterTypes.join('_');
  return parameterTypesKey;
}
// 導出工廠函數(shù)
export function OverloadFactory() {
  return new OverloadJS()
}

代碼解釋

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

步驟一

代碼先定義了一個 isAssignmentValid 標識,表示當前能否對重載實例或類進行賦值。

步驟二

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

步驟三

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

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

注冊函數(shù)接受兩個參數(shù)一個是需要重載的目標函數(shù),一個是目標函數(shù)接受的參數(shù)類型數(shù)組。

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

接下來,將 isAssignmentValid 標志設置為 true ,表示當前處于合法賦值狀態(tài)。這是為了在注冊函數(shù)時允許對 fnMap 進行賦值操作。

然后,通過將參數(shù)數(shù)組 arr 使用 _ 連接起來,生成一個用于標識參數(shù)類型的 key,賦值給變量 typesKey 。

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

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

這段代碼的作用是在注冊函數(shù)時,將函數(shù)和對應的參數(shù)類型映射存儲起來,以便后續(xù)根據(jù)傳入的參數(shù)類型選擇正確的函數(shù)版本進行調(diào)用。

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

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

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

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

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

接下來,通過訪問 fnMap 屬性,獲取存儲在 fnMap[fn.name][typesKey] 位置的目標函數(shù),并將其賦值給變量 targetFn 。

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

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

步驟四

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

基礎使用

創(chuàng)建重載實例

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

注冊同名函數(shù)

OverloadInstance.reg(function exampleFn(param1, param2) { //注冊同名函數(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)

代碼用例

簡單用例:

let x = OverloadFactory() // 創(chuàng)建重載實例
x.reg(function name(a) { // 注冊同名函數(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')

運行結果:

代碼缺陷

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

總結

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

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

相關文章

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

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

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

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

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

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

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

    JS打斷點的六種常用姿勢你用過幾種

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

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

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

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

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

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

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

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

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

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

    當頁面表單沒有提交直接返回時,要提示用戶是否保存當前信息,如果已經(jīng)提交就不提示了,下面小編給大家?guī)砹宋⑿判〕绦螯c擊左上角返回彈窗提示解決思路,感興趣的朋友一起看看吧
    2024-06-06
  • IE8 下的Js錯誤HTML Parsing Error...

    IE8 下的Js錯誤HTML Parsing Error...

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

最新評論