在javascript中可用相同的名字在同一个作用域中定义两个函数,而不会发生错误,但真正使用的是后一个函数。如下:
function doAdd(iNum){ alert(iNum + 100);}
function doAdd(iNum){ alert(iNum + 10)};
doAdd(10);
结果显示“20”,因为第二个doAdd()函数的定义覆盖了第一个定义。
造成这个原因是javascript中的函数实际上是功能完整的对象。Function类可以表示开发者定义的任何函数。用Function类直接创建函数的语法如下:
var function_name = new Function(argument1, argument2, ....,argumentN, function_body);
在这种形式中,每个argument都是一个参数,最后一个参数是函数主体(要执行的代码),这些参数必须是字符串。如下函数:
function sayHi(sName, sMessage){alert("Hello" + sName + "," + sMessage);}可以定义如下:
var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + \",\" + sMessage + \");");
因此,函数只不过是一种引用类型,他们的行为与用Function类明确创建的函数行为相同。所以第一个例子可以写出如下:
doAdd = new Function("iNum", "alert(iNum + 100)");
doAdd = new Function("iNum", "alert(iNum + 10)");
doAdd(10);
很显然,doAdd的值被改成了指向不同对象的指针,函数名只是指向函数对象的引用值,行为就行其他指针一样,甚至可以使两个变量指向同一个函数:
var doAdd = new Function(“iNum”, “alert(iNum + 10)”);
var alsoDoAdd = doAdd;
doAdd(10); //outputs "20"
alseDoAdd(10); //outputs "20"
这里,变量DoAdd被定义位函数,然后alsoDoAdd被声明为指向同一个函数的指针,用这两个变量都可以执行该函数的代码,输出相同的结果“20”。因此,函数名
只是指向函数的变量,那么可以把函数作为参数传递给另一个函数。如下:
function callAnotherFunc(fnFunction, vArgument){ fnFunction(vArgument); }
var doAdd = new Function("iNum", "alert(iNum + 10)");
callAnotherFunc(doAdd, 10); //outputs "20"
在这个例子中,callAnotherFunc()有两个参数——要调用的函数和传递给改函数的参数。
尽管可用Function构造函数创建函数,但最后不要使用它,因为用它定义函数比用传统方式慢的多,不过,所有函数都应该看做是Function类的实例。
因为函数是引用类型,所以他有属性和方法。如属性length为查看默认情况下预期的参数个数提供了一个简单的方式。
Function对象也有与所有对象共享的标准valueof()方法和toString()方法,这两个方法返回的是函数的源代码,在调试时很有用。
值得一提的是javascript函数可以接受任意多个参数(最多25个)。
在函数代码中,有一个特殊对象arguments,开发者无需明确指出参数名,就能访问他们。用arguments[0]可以访问第一个参数的值(第一个参数位于位置0,第二个参数位于位置1,一次类推)。可以用arguments对象检测传递给函数的参数个数,引用属性arguments.length即可。下面的代码将输出每次调用函数使用的参数个数:
function howManyArgs(){ alert(arguments.length); }
howManyArgs("string", 45) //outputs "2"
howManyArgs(); //outputs "0"
howManyArgs(12); //outputs "1"
与其他程序设计语言不同,ECMAScript 不会验证传递给函数的参数个数是否等于函数定义的参数个数,开发者定义的函数都可以接受任意个数的参数(根据Netscape的文档,最多能接受25个),而不会引发任何错误。任何遗漏的参数都会以undefined传递给函数,多余的参数将忽略。
用arguments对象判断传递给函数的参数个数,即可模拟函数重载:
function doAdd(){
if(arguments.length == 1){alert(arguments[0] + 10);}
else if(arguments.length == 2){alert(arguments[0] + arguments[1]);}
}
doAdd(10); //outputs "20"
doAdd(30,20); //outputs "50"
虽然不如重载好,但可以避开ECMAScript的这种限制。
浙公网安备 33010602011771号