函数 | 深刻理解函数名是指向函数的指针

回顾

  • 每一个函数都是Function类型的实例,Function有属性和方法

  • 函数是对象,函数名就是指向函数对象的指针

  • 所有函数对象都会暴露一个只读的name属性,其中包含关于函数的信息

    • 情况一:正常情况 => 标识符,或者字符串化的变量名
    • 情况二:函数没有名称 => 空字符串
    • 情况三:构造函数创建 => anonymous
    • 情况四:如果函数是set get 函数或者使用bind实例化 => 前缀 + 函数名
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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
    console.log(foo.bind(null).name); // bind foo

函数名是函数指针

注意:使用不带括号的函数名会访问函数指针,而不会执行函数

1
2
3
4
5
6
7
8
9
10
11
function sum(num1, num2) {
return num1 + num2;
}

console.log(sum(10, 10)); // 20

let anotherSum = sum; // #1
console.log(anotherSum(10, 10)); // 20

sum = null; // #2
console.log(anotherSum(10, 10)); // 20

以上过程可抽象为下图:

Step1:将sum赋值给anotherSum的时候其实是相当于把指针赋值给anotherSum,于是anotherSum也指向求和函数

Step2:将sum的指针指向null,这并没有改变anotherSum的指针指向,所以并不会影响anotherSum执行

没有重载

重载函数:允许在同一范围中声明几个功能类似的同名函数,但是同名函数的签名不同,比如形参类型不同,数量不同等。

如果在JS中定义两个同名函数会发生什么情况?

1
2
3
4
5
6
7
8
9
function add(num) {
return num += 100;
}

function add(num) {
return num+=200
}

console.log(add(100)); // 300

从打印结果来看,前一个add被后一个add给覆盖了

其实理解了”函数名是函数指针“之后,很容易能够抽象出下图:

当然,函数表达式也是一样的情况,这里不再赘述。