JavaScript高级程序设计(第4版)
上QQ阅读APP看书,第一时间看更新

10章 函数

本章内容

❑ 函数表达式、函数声明及箭头函数

❑ 默认参数及扩展操作符

❑ 使用函数实现递归

❑ 使用闭包实现私有变量

函数是ECMAScript中最有意思的部分之一,这主要是因为函数实际上是对象。每个函数都是Function类型的实例,而Function也有属性和方法,跟其他引用类型一样。因为函数是对象,所以函数名就是指向函数对象的指针,而且不一定与函数本身紧密绑定。函数通常以函数声明的方式定义,比如:

    function sum (num1, num2) {
      return num1 + num2;
    }

注意函数定义最后没有加分号。

另一种定义函数的语法是函数表达式。函数表达式与函数声明几乎是等价的:

    let sum = function(num1, num2) {
      return num1 + num2;
    };

这里,代码定义了一个变量sum并将其初始化为一个函数。注意function关键字后面没有名称,因为不需要。这个函数可以通过变量sum来引用。

注意这里的函数末尾是有分号的,与任何变量初始化语句一样。

还有一种定义函数的方式与函数表达式很像,叫作“箭头函数”(arrow function),如下所示:

    let sum = (num1, num2) => {
      return num1 + num2;
    };

最后一种定义函数的方式是使用Function构造函数。这个构造函数接收任意多个字符串参数,最后一个参数始终会被当成函数体,而之前的参数都是新函数的参数。来看下面的例子:

    let sum = new Function("num1", "num2", "return num1 + num2");   // 不推荐

我们不推荐使用这种语法来定义函数,因为这段代码会被解释两次:第一次是将它当作常规ECMAScript代码,第二次是解释传给构造函数的字符串。这显然会影响性能。不过,把函数想象为对象,把函数名想象为指针是很重要的。而上面这种语法很好地诠释了这些概念。

注意 这几种实例化函数对象的方式之间存在微妙但重要的差别,本章后面会讨论。无论如何,通过其中任何一种方式都可以创建函数。