《JavaScript高级程序设计》学习笔记之JavaScript函数介绍

JavaScript函数介绍

函数对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScrip中的函数使用function关键字来声明,后跟一组参数以及函数体。函数的基本语法如下所示:

function functionName(arg0, arg1, ..., argN) {
  statement;
}

在含有return语句的函数中,函数会在执行完return语句之后停止并立即退出。因此,位于return语句之后的任何代码永远都不会执行。例如:

function sum(num1, num2){
  return num1 + num2;
  alert("Hello World"); //永远不会执行
}

在上面的例子中,由于调用alert()函数的语句位于return语句之后,因此永远不会显示警示框,

当然,一个函数中也可以包含多个return语句,如下例所示:

 function diff(num1, num2){
  if(num1 < num2){
    return(num2 - num1);
  }else{
    return(num1 - num2);
  }
}

另外,return语句也可以不大有任何返回值。在这种情况下,函数在停止执行后将返回undefined值。这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下。比如在下面的例子中,就不会显示警示框:

function sayHi(name, message){
  return;
  alert("Hello " + name + "," + message); //永远都不会调用
}

推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值,否则,如果函数有时返回值,有时候不返回值,会调式代码带来不便。

理解参数

ECMAScript函数的参数与大多数其他语言的参数有所不同。ECMAScript函数不介意传递进来多少个参数, 也不在乎传进来的参数是什么数据类型。也就是说,即使你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数,可以传递一个、三个甚至不传递参数,而解析器永远不会有什么怨言。之所以会这样,原因是ECMAScript中的参数在内部是用一个数组来表示的,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,也无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过arguments对象来访问这个这个参数数组,从而获取传递给函数的每一个参数。

其实,arguments对象只是与数组类似(它并不是Array的实例),因为可以使用方括号语法访问它的每一个元素(即第一个元素是arguments[0],第二个元素是arguments[1],以此类推),使用length属性来确定传递进来多少个参数。在前面的例子中,sayHi()函数的第一个参数的名字叫name,而该参数的值也可以通过访问arguments[0]来获取。因此,该函数也可以像像下面这样重写,即不显示地使用命名参数:

function sayHi(){
  alert("Hello " + arguments[0] + "," + arguments[1]);
}
sayHi("Wangwei", "how are you today?");

这个重写后的函数中不包含命名的参数,虽然没有使用name和message标识符,但函数的功能依旧。这个事实说明了ECMAScript函数的一个重要特点:命名的参数只提供便利,但不是必须的。另外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但在ECMAScript中,没有这些条条框框,解析器不会验证命名参数。

通过访问arguments对象的length属性可以获知有多少个参数传递给了函数。下面这个函数会在每次被调用时,输出传入其中的参数个数:

function howManyArgs() {
  alert(arguments.length);
}
howManyArgs("string", 45); //2
howManyArgs();             //0
howManyArgs(12);           //1

执行以上代码会依次出现3个警示框,分别显示2、0和1。由此可见,开发人员可以利用这一点让函数能够接收任意个参数并分别实现适当的功能。如下面的例子:

function doAdd() {
  if(arguments.length == 1) {
    alert(arguments[0] + 10);
  }else if(arguments.length == 2) {
    alert(arguments[0] + arguments[1]);
  }
}
doAdd(10);     //20
doAdd(30, 20); //50

另一个与参数相关的重要方面,就是arguments对象可以与命名参数一起使用,如下面的例子所示:

function doAdd(num1, num2) {
  if(arguments.length == 1) {
    alert(num1 +10);
  }else if(arguments.length == 2){
    alert(arguments[0] + num2);
  }
}
doAdd(10); //20
doAdd(30, 20); //50

在重写后的这个doAdd()函数中,两个命名参数都与arguments对象一起使用,由于num1的值与arguments[0]的值相同,因此它们可以互换使用(当然,num2和arguments[1]的值也是如此)。

关于参数还应记住最后一点:没有传递值的命名参数将自动被赋予undefined值,这就跟定义了变量但又没有初始化一样。例如,如果只给doAdd()函数传递了一个参数,则num2中就会保存undefined值。ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。









猜你喜欢

转载自blog.csdn.net/qq_36595013/article/details/80286043