6. 函数
函数对于任何一个语言都是一个核心概念。通过函数可以封装任意多条语句,而且可以在任何地方,任何时候调用执行。ECMAScript中的函数使用function关键字来声明,后跟一组参数以及函数体。下面是一个简单的例子:
function sayHi(message){
alert("hello" + message);
}
sayHi("how are u?");
ECMAScript中的函数在定义时不必指定是否返回值。事实上,任何函数都可以通过return关键字后跟要返回的值来实现返回值。请看下面的例子:
function sum(num1, num2){
return num1 + num2;
}
这个函数会在执行完return语句后立刻退出,因此,任何位于return后的语句都不会被执行。
ECMAScript函数的参数与大多数其他语言中的函数参数不同。ECMAScript函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即使你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数,可以传递一个,三个甚至不传递任何参数。根本原因时ECMAScript中的函数参数其本质上是一个数组,函数接收到的始终是一个数组,因此并不关心数组的大小,以及每个元素的具体类型。事实上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
事实上,arguments对象只是与数组类似(它并不是Array的实例),可以使用方括号语法访问它的每一个元素,并使用length属性确定传进来多少个参数。因此,上文中的sum函数也可以这样重写:
function sum(){
return arguments[0] + arguments[1];
}
以上这个例子体现了ECMAScript函数的一个重要特点:命名的参数只提供更好的可读性,但不是必须的。其他语言可能需要事先创建一个函数签名,将来的调用必须与该签名一致。但在ECMAScript中,没有这些条条框框,解析器不会验证命名参数。
关于arguments参数,还有一点比较有意思。那就是它的值永远与它对应命名参数的值保持同步。例如:
function update(num){
arguments[0] = -1;
console.log(num); //-1
num = 3;
}
var num = 5;
update(num);
alert(num); //5
上面的例子中,修改了arguments[0],对应的num变量的值也修改了,不过,这并不意味着这两个值访问的是同一个内存空间;它们的内存空间是独立的,但它们Nederland值会同步。但这种影响是单向的,修改命名参数不会改变对应arguments对象中的值。另外,arguments对象的长度是由传入的参数个数决定的,因此如果上面的方法调用时不传入num参数,那么arguments[0]的赋值不会反映到命名参数中,num输出为undefined。
严格模式下,不存在arguments的自动同步。另外,重写arguments的值会导致语法错误。
ECMAScript中参数传递都是值传递,不存在引用传递。
ECMAScript中不存在函数签名,因为函数的参数是由包含零个或多个值的数组组成,而没有函数签名,意味着无法实现函数重载。
如果ECMAScript中定义了两个相同名字的函数,则该名字只属于后定义的函数。
网友评论