我们先看一下下面的html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<button onclick="echo()">echo</button>
</div>
<div>
<button onclick="echo(1)">echo(1)</button>
</div>
<div>
<button onclick="echo(1,2)">echo(1,2)</button>
</div>
</body>
<script>
function echo() {
alert("我执行了echo()")
}
function echo(a) {
alert("我执行了echo(a)");
}
</script>
</html>
我们再看一下其中的javascript代码
<script>
function echo() {
alert("我执行了echo()")
}
function echo(a) {
alert("我执行了echo(a)");
}
</script>
我们点击按钮最终调用的都是
function echo(a) {
alert("我执行了echo(a)");
}
这就跟我们的常识有点出入了,要知道像Java、Scala、Python这样的语言都是支持方法重载的,也就是在一个类中(你可以理解为文件中)是可以定义同名但是入参不同的函数的,这就叫方法的重载
比如
public String echo(){
}
public String echo(String a){
}
public String echo(String a ,String b){
}
上面定义的三个函数,在调用的时候,编译器会尽最大努力进行精确匹配 ,如果你写
echo()
那么调用的就是第一个 echo()
函数;如果你写
echo("1")
那么调用的就是 第二个 echo(String a)
; 如果你写
echo("1","2")
那么调用的就是 第三个 echo(String a ,String b)
;
这似乎更符合人类的感官。但是 JavaScript 语言这类语言却反其道而行之,JavaScript 遇到重名的函数,走的是覆盖的逻辑,也就是最后定义的函数会覆盖前面的函数,这样,第二个 echo(a) 函数就是最终的名叫 echo 的函数,而 javsscript 中之前的两个函数就相当于没有定义一样。
这类语言一般都是面向过程的语言,javascript 最开始的时候确实就是面向过程的,后来随着 EMAC 标准的制定,逐渐变得有点多范式的感觉了。
这里javascrip 语言真是特别灵活 ,对于 echo(1,2) 这个调用,他居然也能正常的调用到 echo(a) ,按照我们的理解,echo(1,2) 需要两个入参,但是我们并没有定义有两个入参的 echo(a,b) 这样的函数要,理论上应该报错才对啊, 这你就想错。 如果你这样瞎传参数,无论括号里面有多少个 参数,也只有第一个参数有作用,会调用到 echo(a) ,然后把第一个参数赋值给a,剩下的参数就不能显示的获取了。 这种特性有点类似于结构,一些函数编程语言会提供这种高级的用法,期待Java也能慢慢支持这种语法糖吧。