在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的这种限制。

posted on 2011-01-28 11:24  飞翔-方向 积累 沉淀  阅读(1216)  评论(1)    收藏  举报