1. 程式人生 > >從兩個角度理解為什麼 JS 中沒有函式過載

從兩個角度理解為什麼 JS 中沒有函式過載

函式過載是指在同一作用域內,可以有一組具有相同函式名,不同引數列表(引數個數、型別、順序)的函式,這組函式被稱為過載函式。過載函式通常用來宣告一組功能相似的函式,這樣做減少了函式名的數量,避免了名字空間的汙染,對於程式的可讀性有很大的好處。

但是在 JS 如果不通過一些方法是無法實現過載的,可以從以下兩個角度去理解。

1. 方法簽名

方法簽名指的是函式的名稱加形參列表,並且通過函式的名稱或者形參列表都可以區分出是不同的函式。

JS 中通過形參是沒有辦法區分出不同的函式的,只能通過函式的名稱區分出不同的函式,現在我們來看一下下面的例子.

function add(a, b) {
  return a + b;
}
function add(a, b) {
  return a + b + 1;
}

上述實際上是一個函式,後面的函式 add 會覆蓋前面的函式,究其原因還是因為 JS 是弱型別的語言,a 和 b 實際上都是用 var 宣告的,等價於

function add(var a, var b) {
  return a + b;
}

所以在 JS 中只能通過函式名稱來辨別是不是同一個函式,形參是沒有用的。

但是在強型別的語言中就是可以的,例如在 c 語言中,定義函式時形參必須要指定型別,向裡面傳值的時候也必須傳遞指定型別的值。函式名相同,形參名不同的函式也會被認為是不同的函式。

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}
double add(double a, double b) {
    return a + b + 1;
}

int main() {
    printf("第一種宣告函式結果 add(1, 3)= %d \n", add(1, 3));
    printf("第二種宣告函式結果 add(1.0, 3.0)= %lf \n", add(1.0, 3.0));
}

上述兩個函式是不同的,可以列印一下結果驗證一下。

所以,在 C 語言這種強型別的語言中是可以實現函式過載的,JS 這種弱型別的語言是不可以的。

2. 函式指標

另一中理解的角度是可以將函式名想象為指標,函式名中存放的是函式體存放的地址。還是通過程式碼來說明。

function add(a, b) {
  return a + b;
}
function add(a, b) {
  return a + b + 1.0;
}

上面的兩種宣告方式等價於

var add = function (a, b) {
  return a + b;
}
add = function (a, b ) {
  return a + b + 1.0;
}

最終 add 實際上指向的是第二個函式,第一個函式被覆蓋了,所以最終呼叫 add 時呼叫的也是第二個函式,並不能實現函式的過載。

console.log(add(1, 3)) // 5

完,如有不恰當之處,歡迎指正哦。