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

来源:互联网 发布:北明软件 编辑:程序博客网 时间:2024/06/06 07:29

函数的参数

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中是不可能存在的。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 户户通位置锁定模块异常3怎么办 逆战安全系统检测客户端异常怎么办 电视户户通位置信息模块异常怎么办 苹果手机wi-fi模块坏了怎么办 xp本地连接受限制或无连接怎么办 公司没帮二级建造师延续注册怎么办 考造价师考过了年限不够怎么办? 上海众非称重不显示数字怎么办 宝骏630防火墙隔热棉掉了怎么办 冷车启动水温报警灯亮了怎么办 租铺位面积比合同面积小怎么办 农村村民建房领居不肯签名怎么办 车祸死者家属不来协商赔偿怎么办 26岁想回去当老师了怎么办 面包车排量小空调带不凉快怎么办 科三包过不给退钱人跑了怎么办 护师职称考试成绩单丢了怎么办 河南二级建造师报名地址填错怎么办 山东以前的企业没有消防备案怎么办 重庆渝北初级审核时间过了怎么办 初级职称复核毕业证弄丢了怎么办 杭州公租房选房后变更单位的怎么办 契税交了贷款办不下来怎么办 天津公租房住满5年后怎么办 大江里钓鱼水流太急立不住漂怎么办 房子定金交了不想要了怎么办 房子付了首付不想要了怎么办 三国大时代4王越死了任务怎么办 红米2卡顿反应慢怎么办 国税和地税合并新进的公务员怎么办 买车合格证不给我们要怎么办 初级会计报名信息表填写错误怎么办 跨国快递需要收件人自行清关怎么办 腋下有异味怎么办邀约成都真愛 腋下有异味怎么办犀利成都真愛 腋下有异味怎么办有信成都真愛 成都车牌网上选号次数用完了怎么办 在志愿服务中遇到突发状况怎么办 商铺没有房产证不能办理消防怎么办 亳州办事大厅登录密码忘记了怎么办 户口已迁出结婚证丢了怎么办