天天看點

JS 中沒有函數重載,又是如何實作函數重載的呢?

JS 中沒有函數重載,又是如何實作函數重載的呢?

面試官問你 JS 是如何實作函數重載的?你會怎麼回答?

你會不會疑問我在書裡看的明确講 JS 是沒有函數重載的,面試官說能實作,那肯定是有辦法的呀,該如何實作呢?

一、什麼是函數重載?​

重載函數指的是兩個或兩個以上的同名函數,實作一個函數名有多種功能。

函數重載要求編譯器能夠在調用函數時唯一确定,應該調用的是哪個函數?由于同名函數有多個,在确定函數實作時,需要根據函數的參數的個數和類型來區分,即實作函數重載時,要求同名函數的參數個數或類型不一緻,否則将無法實作函數重載。

重載的特點:

  • 同名的多個函數。
  • 不同的參數。
二、JS中有函數重載嗎?

我在閱讀《JavaScript 進階程式設計(第三版)》一書,在第五章看到明确的提示 JS 沒有函數重載。

JS 中沒有函數重載,又是如何實作函數重載的呢?

我們在 《JavaScript 進階程式設計(第三版)》 書中能看到,JS 中的同名函數,前面的會被最後面的函數覆寫掉,根本無法實作多種功能,如:

function add(a,b) {
 return a+b
}
function add(a, b, c) {
 return a + b + c
}
console.log(add(1,2)); // NaN
console.log(add(1,2,3 ));// 6      

如果我們需要使用 JS 實作上述 add 方法,将兩個或三個數值進行求和,該怎麼解決呢?

解決1:利用 arguments

function add() {
 var reg = arguments;
 if (reg.length == 2) {
  return reg[0] + reg[1]
 } else if(reg.length == 3) {
  return reg[0] + reg[1] + reg[2]
 }
}
console.log(add(1, 2)) //3
console.log(add(1, 2, 3)) //6      

上述方法雖然實作了上述簡單功能,勉強能算得上是一種函數重載的實作方法,但是存在一定的弊端。

它的缺點:

  • 如果功能複雜時,代碼量過大。
  • 不利于維護和複用。

這時候問題來了,利用 JS 如何實作呢?可以通過閉包的形式可以簡單地實作。

三、JS 如何實作重載?
function addMethodToObject (obj, name, fn) {
 const temp = obj[name]
 obj[name] = function () {
  if (fn.length === arguments.length) {
   return fn.apply(obj, arguments)
  } else if (typeof temp === 'function') {
   return temp.apply(obj, arguments)
  }
 }
}      

上述方法用來給一個對象添加自定義方法,能夠接收三個參數:

  1. 需要添加方法的對象
  2. 自定義方法名
  3. 定義方法具體要實作的功能,通過回調實作
addMethodToObject(group, 'find', function () {
  return {
    peoples: this.peoples,
    count: this.peoples.length
  }
})
addMethodToObject(group, 'find', function (isMale) {
  if (!!isMale) {
    const male = this.peoples.filter(item => item.sex === 'male')
    return {
      peoples: male,
      count: male.length
    }
  } else {
    const female = this.peoples.filter(item => item.sex === 'female')
    return {
      peoples: female,
      count: female.length
    }
  }
})
addMethodToObject(group, 'find', function (elder, age) {
  if (!!elder) {
    const elder = this.peoples.filter(item => item.age >= age)
    return {
      peoples: elder,
      count: elder.length
    }
  } else {
    const younger = this.peoples.filter(item => item.age < age)
    return {
      peoples: younger,
      count: younger.length
    }
  }
})
const group = {
    total: 10,
    male: 6,
    female: 4,
    peoples: [{
      age: 12,
      sex: 'male'
    }, {
      age: 18,
      sex: 'female'
    }]
}
group.find()
group.find(1)
group.find(0, 15)      

總結:JS 沒有函數重載,但是可以實作函數重載。

學習更多技能

請點選下方公衆号

繼續閱讀