當前位置: 妍妍網 > 碼農

網易面試官:請你實作一下JS多載?可不是TS多載哦!

2024-03-21碼農

前言

大家好,我是林三心, 用最通俗易懂的話講最難的知識點 是我的座右銘, 基礎是進階的前提 是我的初心。今天給大家講一道題,是一道網易的面試題

  • 一位同學:「如何實作JS多載?」

  • 我:「JS有多載嗎?不是TS才有嗎?」

  • 一位同學:「有的,這是網易一道面試題」

  • 我:「好吧我想想哈!」

  • image.png

    什麽是多載

    我第一次看到 多載 這個詞還是在以前學習 Java 的時候,我一直覺得 JavaScript 是沒有多載的,直到 TypeScript 的出現,所以我一直覺得 JavaScript 沒有多載, TypeScript 才有,但是現在看來我是錯的。

    我理解的多載是:同樣的函式,不同樣的參數個數,執行不同的程式碼,比如:

    /*
    * 多載
    */

    functionfn(name{
    console.log(`我是${name}`)
    }
    functionfn(name, age{
    console.log(`我是${name},今年${age}歲`)
    }
    functionfn(name, age, sport{
    console.log(`我是${name},今年${age}歲,喜歡運動是${sport}`)
    }
    /*
    * 理想結果
    */

    fn('林三心'// 我是林三心
    fn('林三心'18// 我是林三心,今年18歲
    fn('林三心'18'打籃球'// 我是林三心,今年18歲,喜歡運動是打籃球

    但是直接在 JavaScript 中這麽寫,肯定是不行的,咱們來看看上面程式碼的實際執行結果,可以看到,最後一個 fn 的定義,把前面兩個都給覆蓋了,所以沒有實作 多載 的效果

    我是林三心,今年undefined歲,喜歡運動是undefined
    我是林三心,今年18歲,喜歡運動是undefined
    我是林三心,今年18歲,喜歡運動是打籃球

    我的做法

    其實,想要實作理想的 多載 效果,我還是有辦法的,我可以只寫一個 fn 函式,並在這個函式中判斷 arguments 類陣列的長度,執行不同的程式碼,就可以完成 多載 的效果

    functionfn() {
    switch (arguments.length) {
    case1:
    var [name] = arguments
    console.log(`我是${name}`)
    break;
    case2:
    var [name, age] = arguments
    console.log(`我是${name},今年${age}歲`)
    break;
    case3:
    var [name, age, sport] = arguments
    console.log(`我是${name},今年${age}歲,喜歡運動是${sport}`)
    break;
    }
    }
    /*
    * 實作效果
    */

    fn('林三心'// 我是林三心
    fn('林三心'18// 我是林三心,今年18歲
    fn('林三心'18'打籃球'// 我是林三心,今年18歲,喜歡運動是打籃球

    但是那位同學說,網易的面試官好像覺得這麽實作可以是可以,但是還有沒有更好的實作方法,我就懵逼了。

    高端做法

    image.png

    經過了我的一通網上尋找資料,發現了一種比較高端的做法,可以利用 閉包 來實作 多載 的效果。這個方法在JQuery之父John Resig寫的【secrets of the JavaScript ninja】中,這種方法充分的利用了 閉包 的特性!

    functionaddMethod(object, name, fn{
    var old = object[name]; //把前一次添加的方法存在一個臨時變量old裏面
    object[name] = function () // 重寫了object[name]的方法
    // 如果呼叫object[name]方法時,傳入的參數個數跟預期的一致,則直接呼叫
    if (fn.length === arguments.length) {
    return fn.apply(thisarguments);
    // 否則,判斷old是否是函式,如果是,就呼叫old
    elseif (typeof old === "function") {
    return old.apply(thisarguments);
    }
    }
    }
    addMethod(window'fn', (name) => console.log(`我是${name}`))
    addMethod(window'fn', (name, age) => console.log(`我是${name},今年${age}歲`))
    addMethod(window'fn', (name, age, sport) => console.log(`我是${name},今年${age}歲,喜歡運動是${sport}`))
    /*
    * 實作效果
    */

    window.fn('林三心'// 我是林三心
    window.fn('林三心'18// 我是林三心,今年18歲
    window.fn('林三心'18'打籃球'// 我是林三心,今年18歲,喜歡運動是打籃球

    參考資料

  • 淺談JavaScript函式多載

  • 結語

    如果你覺得此文對你有一丁點幫助,點個贊,鼓勵一下林三心哈哈。或者加入我的群哈哈,咱們一起摸魚一起學習 : meron857287645