首先我们要搞懂什么是重载?
以Java的方法和JavaScript的函数来比较一下:
- Java : 是可以用
方法签名
来唯一确定一个方法。所谓方法签名包括:方法名、参数类型和参数顺序、参数个数这几个要素。所以,如果两个方法名称相同,但是只要其他要素(例如参数类型、参数个数)不同,编译器就会认为是不同方法。从而可以存在同名的不同方法,导致了重载
现象。 - JavaScript:函数(或对象方法)完全靠函数名称唯一确定,,JS不将参数列表作为区分函数的依据。更关键的是,在JS中,函数是作为一种特殊对象类型存在的,函数的名字只是一个普通的变量,本质与
var a ;
中的变量a
没什么区别。所以如果你先后定义了两个同名函数,实际上相当于先后将两个函数对象绑定到了同一个变量上,所以后者必然覆盖前者,不会共存,也自然不存在重载
了。
没有重载的例子:
function addNum(num) {
return num + 10;
}
function addNum(num) {
return num + 20;
}
//调用
var result = addNum(10); //30
以上代码,类似于定义一个变量,然后变量再重新赋值,所以导致了第二个函数覆盖了第一个函数。JavaScript函数没有签名
,因为其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可能做到的。 但是我们可以模拟重载。
模拟重载的例子:
思路:就是通过arguments对象
实现,通过判断参数的个数(使用length属性
来确定传递进来多少个参数),通过检查传入函数中参数的类型和数量并作出不同的反应,就可以模仿方法的重载。
function addNum(){
if(arguments.length === 1) {
return arguments[0];
} else {
var result = 0, i = 0;
while(i < arguments.length) {
result = result + arguments[i];
i++;
}
return result;
}
return arguments.length;
}
//调用
var f1 = addNum(1,2,4,1); // 8
var f2 = addNum(); // 0
var f3 = addNum(2); // 2
小结
所以,JS中的函数虽然也叫函数,但是别忘了它本质上还是一种对象,只不过是一种比较特殊的具有可调用特征的对象罢了。
当然,JS完全可以设计成支持重载,但是为什么不支持呢?我觉得,可能跟JS一开始的目标就是要设计成一种简单的、动态类型的语言有关。增加了重载,就没那么简单了,而且参数还不能动态传递了。