以下内容是我初次翻开《Javascript高级程序设计》这本书时所看到的,关于“函数”的一些内容的摘抄。
返回值:
ECMAScript中和函数在定义时不必指定是否返回值,任何函数在任何时候都可以通过return语句后跟需要返回的值来实现返回值。函数会在执行完return语句后停止并退出。因此,位于return语句之后的任何代码都永远不会被执行。在没有写return语句的时候,函数默认返回的是一个undefined。
严格模式对函数的一些限制:
- 不能把函数命名为eval和arguments;
- 不能把参数命名为eval和arguments;
- 不能出现两个命名参数同名的情况。
如果出现以上情况,就会导致语法错误,代码无法执行。
参数:
ECMAScript中函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript函数不介意产地进来多少个参数,也不在乎传进来的参数是什么类型。也就是说,即便你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递任意多个,或者不传参数。原因在于,ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不去关心这个数组中包含了什么。
在函数体内,可以通过arguments对象来访问参数数组。arguments对象与数组类似,但不是Array的实例。如果想要获得传递进来的参数的值,可以通过使用方括号语法来访问。如:arguments[0]就是传递进来的第一个参数的值,第二个就是arguments[1]这样,以此类推。由于这个原因,函数在定义时,可以不用在小括号内写出参数的名字,也可以接收传进来的参数。--这是ECMAScript函数的一个重要特点:命名的参数只提供便利,但不是必须的。解释器不会验证命名参数,在函数调用时也就没有命名参数与该签名必须一致的说法。
arguments对象的length属性可以获知有多少个参数传递给了函数。如代码示例1这样使用。
代码示例1:
function doAdd(num1, num2){
if ( arguments.length == 1) {
alert(num1 + 10);
} else if ( arguments.length == 2) {
alert( arguments[0] + num2);
}
}
另:arguments对象还有一个特殊的行为。它的值永远与对应命名参数的值保持同步。
代码示例2:
function doAdd( num1, num2) {
arguments[1] = 10;
alert( arguments[0] + num2);
}
每次执行doAdd()函数都会重写第二个参数,将其值改为10.因为arguments对象中的值会自动反应到对应的命名参数,所以修改arguments[1]也就修改了num2,结果它们的值都会变为10.不过,它们的内存空间是独立的,并不是相同的内存空间,只是值会同步。
如果只传入一个参数,那么arguments[1]设置的值不会反应到命名参数中(也就是示例2中的num2)。这是因为arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数个数决定的。
另外,没有传递值的命名参数将自动被赋予undefined值。
严格模式下,对如何使用arguments对象做出了一些限制:
首先,像前例中那样的赋值会失效。
其次,重写arguments的值会导致语法错误。
没有重载:
由于没有函数签名这个特性,ECMAScript中的函数无法像其他一些语言一样实现真正的函数重载。如果定义了两个名字相同的函数,则该名字只属于后定义的函数。如此,只能通过检查传入参数的类型和数量并作出不同反应来模仿函数重载。