本文深入解析JavaScript中Function对象的本质,阐明函数即对象的原理。通过代码示例说明JS不支持传统方法重载,而是通过同名函数覆盖实现,并介绍利用arguments对象和length属性模拟重载的技巧。此外,详细讲解Function构造函数接收字符串参数的特性及函数length属性的含义,帮助开发者掌握JS函数的高级用法。
JavaScript Function对象本质与重载机制
在JavaScript语言体系中,函数(function)本质上也是一种对象。
JavaScript并不支持传统面向对象语言中的方法重载机制。
具体而言,JS环境中不存在基于参数类型或数量区分的函数重载概念。
以下通过具体代码示例进行说明:
代码实现如下:
<html>
<head>
<script type="text/javascript">
function add(number)
{
alert(number + 20);
}
function add(number, number1)
{
alert(number + 30);
}
add(10);
</script>
</head>
<body>
</body>
</html>运行上述网页代码时,弹出的提示框显示结果为40。
这一现象表明,尽管第二个函数定义包含两个参数,但实际执行时调用的是后定义的函数版本。
若交换两个函数的定义顺序,再次运行代码,弹窗将显示30。这证实了无论传入参数个数如何,JavaScript始终调用同名函数的最后定义版本。
如何解释这一行为特征?
根本原因在于函数声明在底层实际上是构建了一个对象引用:
等效代码逻辑如下:
<html>
<head>
<script type="text/javascript">
function add(number)
{
alert(number + 20);
}
/*
上述函数声明等价于以下赋值语句:
var add = function(number)
{
alert(number + 20);
}
*/
function add(number, number1)
{
alert(number + 30);
}
/*
同理,第二个函数声明等价于:
var add = function(number, number1)
{
alert(number + 30);
}
*/
add(10);
</script>
</head>
<body>
</body>
</html>
由此可见,变量add最终指向的是后定义的函数对象。在调用时,传入的实参会按顺序赋值给形参,未提供值的形参则默认为undefined。
JavaScript在函数调用时不严格校验参数数量。当实参个数少于形参个数时,允许调用,未赋值的形参值为undefined。
反之,若实参个数多于形参个数,调用依然成功,但多余的实参会被忽略,仅前几个形参参与运算。
Function构造函数与字符串参数
Function对象详解
JavaScript内置了Function对象,所有用户自定义的函数均属于Function类型的实例。
Function构造函数接收的所有参数均为字符串类型。其中,最后一个参数代表函数体的代码字符串,而前面的参数则定义函数所需的形参名称。
具体使用示例如下:
代码实现如下:
<html>
<head>
<script type="text/javascript">
var add = new Function("number", "number1", "alert(number + number1);");
var add = new Function("number", "alert(number + 20);");
add(10, 30);
</script>
</head>
<body>
</body>
</html>
利用arguments对象模拟函数重载
隐含对象arguments解析
在JavaScript中,每个函数内部都隐含存在一个arguments对象,用于存储调用时实际传递的参数列表。
arguments对象的内容与函数的形式参数定义及其数量无关,它独立反映实际传入的数据。
arguments对象包含一个有用的属性length,用于获取实际传递参数的个数。利用这一特性,可以手动模拟实现函数的重载效果:
参考练习代码如下:
代码实现如下:
<html>
<head>
<script type="text/javascript">
function add(number1, number2)
{
alert(arguments.length);
alert(arguments[0]);
alert(arguments[1]);
alert(arguments[2]);
}
//add(2, 3, 4);
function add2()
{
if(1 == arguments.length)
{
alert(arguments[0]);
}
else if(2 == arguments.length)
{
alert(arguments[0] + arguments[1]);
}
else if(3 == arguments.length)
{
alert(arguments[0] + arguments[1] + arguments[2]);
}
}
add2(3);
add2(3, 4);
add2(3, 4, 5);
</script>
</head>
<body>
</body>
</html>
每个函数对象都具备一个length属性,该属性值表示函数定义中期望接收的参数个数(即形参数量)。
需注意,函数对象的length属性与arguments.length不同,后者表示调用时实际传入的参数个数。
具体示例如下:
代码实现如下:
<html>
<head>
<script type="text/javascript">
var add = function(num, num2, num3)
{
alert(num + num2 + num3);
}
alert(add.length); //输出3
add(1, 2, 3);
var add2 = function()
{
}
alert(add2.length); //输出0
</script>
</head>
<body>
</body>
</html>