您的位置:首页 > Web前端 > JavaScript

JavaScript深入理解函数参数列表及“不存在重载”

2016-04-03 11:36 1056 查看

函数的参数

JS和其他大多数语言一个较为明显的区别就在于函数参数的处理上。因为在JS中调用函数的时候,传入的参数数据类型是可以不固定的,个数也无所谓多少个。听起来很奇怪,实际上,JS中的参数在内部是用一个数组表示的,不论传入的参数属于什么数据类型,有多少个,函数接收的都是这个数组。解析器并不对数组内容进行检查。(在JS中,数组的长度是可变的,存储元素的类型也是不固定的。)

我们知道了函数参数保存在一个数组中,那么我们如何去访问这个数组呢?————通过argument对象。argument对象是函数内部的一个对象,它存储着传入函数的所有参数。类似于数组,我们可以通过argument[0],argument[1]这样的方式去访问传入的参数。(但argument并不是Array的实例!)argument拥有一个名为length的属性,该属性的值表示实际传入参数的个数。

我们来看一个例子:

function info(name, age) {
alert("hi " + name + ", you are " + age + " years old.");
}


我们定义上面的函数,然后通过如下方式调用:

info("Tom", 23);


结果会输出:

hi Tom, you are 23 years old.


以上的过程都理所当然,正如我们在Java,c/c++中一样。我们这样去调用info()函数当然没有问题,但是可能并没有理解JS中函数真正的特性。事实上,我们也可以用以下的方式来调用函数:

info("Tom");


得到以下输出:



我们只传入了一个参数,因此在访问第二个参数age的时候得到了undefined值,我们在访问数组未赋值的元素时也会返回undefined值。不论我们实际传入函数的参数是什么数据类型,有多少个参数,函数接收到的永远是那个通过arguments对象访问的数组。当我们只传入了一个参数时,访问第二个参数就得到了undefined值。

实际上,上面的info()方法我们完全可以这样写:

function info() {
alert("hi " + arguments[0] + ", you are " + arguments[1] + " years old.");
}


当我们用info(“Tom”, 23)来调用这个函数的时候,同样会得到:

hi Tom, you are 23 years old.


如果我们看得深入一点,会发现:我们在函数定义时,在圆括号中写入的命名参数,只不过是为了方便阅读,方便调用时更好地传入合适的参数,方便在函数内部更便利地使用这些参数罢了。实际上,写不写这些命名参数都不会影响函数的功能。

我们甚至可以定义这样的函数:

function math(abc, def, ghi) {
if(arguments.length == 1) {
return arguments[0];
}
if(arguments.length == 2) {
return arguments[0] + arguments[1];
}
}


于是在我们传入一个参数的时候返回该参数本身,传入两个参数的时候返回这两个参数的和。至于定义函数时参数列表是什么,根本就无所谓。

上面定义的function math(abc, def, ghi)函数,根据传入参数个数的不同执行不同的操作,有点类似于函数重载的意思了。然而JS中函数并不存在重载!为什么?

为什么JS没有重载

理解JS中为什么不存在函数重载,首先要搞清楚函数重载的概念:

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。


我们上面说过,JS中参数列表对函数的功能是没有丝毫影响的!参数列表只是为了我们更方便地使用函数而设置的,真正调用函数时,起作用的永远是一个存放参数的数组。仅凭这一点,指望通过不同的形参列表实现函数重载就是不可能做到的。

另外,在JS中,函数实际上是Function类型的实例。函数是对象,函数名实际上就是指向函数对象的指针。所以我们在定义同名函数的时候,后定义的函数只不过是覆盖了先定义函数的引用变量罢了。

例如:

function fun(arg1) {
return arg1;
}

function fun(arg1, arg2) {
return arg1 + arg2;
}


本质上和以下代码是一样的:

function fun(arg1) {
return arg1;
}

fun = function() {
return arguments[0] + arguments[1];
}


fun变量首先指向首先定义的函数

function fun(arg1) {
return arg1;
}


然而在创建第二个函数的时候,该变量被覆盖了,重新指向新定义的函数。因此重载在JS中是不可能存在的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: