JavaScript函数重载(js函数重载)
一个猜测
猜测
Java中的方法(函数)重载:类里面的两个或多个重名的方法,方法的参数个数、类型至少有一个不一样,构成了方法重载。
由于js参数类型都为var,我们由此提出大胆猜测:js函数重载只能通过形参的个数不同来区分。
验证
来操作一波:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function add(){
document.writeln("没有参数,你让我加什么?")
}
function add(a,b){
return a+b;
}
function add(a,b,c) {
return a+b+c;
}
document.writeln(add());
document.writeln(add(1,2));
document.writeln(add(2,3,4));
</script>
</body>
</html>
咦呀!年轻人不讲武德,来骗,来否定我69岁的老猜测。
再尝试
这个输出结果看的我一脸懵,没事,再来尝试一下别的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function comeon() {
document.writeln("无参一身轻");
document.write("<br>");
}
function comeon(i) {
document.writeln("一参是为"+i);
document.write("<br>");
}
function comeon(i,j){
document.writeln("二参数更有"+i+"和"+j);
document.write("<br>");
}
comeon();
comeon(1);
comeon(1,2);
</script>
</body>
</html>
再看下面这段:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function comeon() {
document.writeln("无参一身轻");
document.write("<br>");
}
function comeon(i) {
document.writeln("一参是为"+i);
document.write("<br>");
}
comeon();
comeon(1);
</script>
</body>
</html>
再看:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function comeon() {
document.writeln("无参一身轻");
document.write("<br>");
}
comeon();
</script>
</body>
</html>
看来,几个同名函数,每次调用,都只会调用参数最多的那个函数。才会出现上面那些奇怪的输出。
等等,真是这样吗?那你就错了,请看如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function comeon() {
document.writeln("无参一身轻");
document.write("<br>");
}
function comeon(i,j){
document.writeln("二参数更有"+i+"和"+j);
document.write("<br>");
}
function comeon(i) {
document.writeln("一参是为"+i);
document.write("<br>");
}
comeon();
comeon(1);
comeon(1,2);
</script>
</body>
</html>
再看:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js函数重载</title>
</head>
<body>
<script type="text/javascript">
function comeon(i,j){
document.writeln("二参数更有"+i+"和"+j);
document.write("<br>");
}
function comeon(i) {
document.writeln("一参是为"+i);
document.write("<br>");
}
function comeon() {
document.writeln("无参一身轻");
document.write("<br>");
}
comeon();
comeon(1);
comeon(1,2);
</script>
</body>
</html>
恍然大悟,原来,对于同名函数,在调用时,js只会调用最后定义的那个函数,这哪里是重载啊,这分明就是“覆盖”啊!前面的定义被后面的定义覆盖了。
结论
猜测不成立,当js函数重名函数形参个数不同时,实际上,后面的定义会覆盖前面的,相当于,所谓重名函数,实际上是一个函数被定义了好几遍,最后一次定义才是最终定义,调用时会调用最后一次定义的函数。
实际上,js不存在重载。
模拟重载
? 虽然我们刚刚的猜想被否定了,但对于本文的第一段代码,能不能对其做一些修改,来达到重载的效果呢?也就是模拟重载。我们自然而然想到,我们能不能够获取函数调用时实参的个数,然后用一个无形参的函数实现与猜想中重载相同的效果呢?
? 那么,无参函数可以接收调用时给的实际参数吗?听起来有点荒谬,没想到还真可以,js的arguments对象可以接收函数调用时的实参,因此,实参多于形参,甚至没有形参时,程序都不会报错,反正你给多少实参我都收着,来者不拒,来一个在我这儿是arguments[0],来第二个是arguments[1],依次类推。arguments对象的length属性,可以获取函数的实参个数。
接下来就好办了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js模拟重载</title>
</head>
<body>
<script type="text/javascript">
function add(){
if(arguments.length==0){
document.writeln("没有参数,你让我加什么?");
document.write("<br>");
}
else if(arguments.length==1){
document.writeln(arguments[0]);
document.write("<br>");
}
else
{
var n = 0;
len = arguments.length;
for (var i = 0; i < len; i++) {
n+=arguments[i];
}
document.writeln(n);
document.write("<br>");
}
}
add();
add(1);
add(1,2);
add(1,2,3);
</script>
</body>
</html>
结论
js中实际上不存在重载,但是我们根据Java重载的思路,实现了对求和函数的模拟重载。Java重载的作用是:减少函数名的数量,避免了名字空间的污染,减少代码行数,提高代码可读性。因此我们在对js进行模拟重载时,也应该考虑这些因素,并非为了模拟重载而模拟重载。
|