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

10.2 函数名

因为函数名就是指向函数的指针,所以它们跟其他包含对象指针的变量具有相同的行为。这意味着一个函数可以有多个名称,如下所示:

    function sum(num1, num2) {
      return num1 + num2;
    }
    console.log(sum(10, 10));           // 20
    let anotherSum = sum;
    console.log(anotherSum(10, 10));   // 20
    sum = null;
    console.log(anotherSum(10, 10));   // 20

以上代码定义了一个名为sum()的函数,用于求两个数之和。然后又声明了一个变量anotherSum,并将它的值设置为等于sum。注意,使用不带括号的函数名会访问函数指针,而不会执行函数。此时,anotherSum和sum都指向同一个函数。调用anotherSum()也可以返回结果。把sum设置为null之后,就切断了它与函数之间的关联。而anotherSum()还是可以照常调用,没有问题。

ECMAScript 6的所有函数对象都会暴露一个只读的name属性,其中包含关于函数的信息。多数情况下,这个属性中保存的就是一个函数标识符,或者说是一个字符串化的变量名。即使函数没有名称,也会如实显示成空字符串。如果它是使用Function构造函数创建的,则会标识成"anonymous":

    function foo() {}
    let bar = function() {};
    let baz = () => {};
    console.log(foo.name);                   // foo
    console.log(bar.name);                   // bar
    console.log(baz.name);                   // baz
    console.log((() => {}).name);          //(空字符串)
    console.log((new Function()).name);   // anonymous

如果函数是一个获取函数、设置函数,或者使用bind()实例化,那么标识符前面会加上一个前缀:

    function foo() {}
    console.log(foo.bind(null).name);     // bound foo
    let dog = {
      years: 1,
      get age() {
        return this.years;
      },
      set age(newAge) {
        this.years = newAge;
      }
    }
    let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age');
    console.log(propertyDescriptor.get.name);   // get age
    console.log(propertyDescriptor.set.name);   // set age