First-class Function (函数是一等公民/头等函数)| 函数式编程

2,005 阅读3分钟

hi~ 我是 无言非影, 很高兴在这里分享我的学习历程。

关于 函数式编程 整理的一些笔记,都统一记录在: 函数式编程专栏


First-class Function (函数是一等公民/头等函数)

当一门编程语言的函数可以被当作变量一样用时,则称这门语言拥有头等函数

  • 有如下特性:
    1. 函数可以被赋值给一个变量;
    2. 函数可以被当作参数传递给其他函数;
    3. 函数可以作为另一个函数的返回值。

1. 把函数赋值给变量

即使你的函数有自己的函数名称,你仍然可以用这个变量名去调用它。

  // 将匿名函数赋值给变量
  const fn = function() {
    console.log("fn_bar");
  }
  fn(); // fn_bar

  // 将有名称的函数赋值给变量
  const fn2 = function name() {
    console.log("fn2_bar");
  }
  fn2(); // fn2_bar

一个函数包裹另一个函数,并且形式也相同时,我们可以认为这是两个一样的函数,可以对其进行精简

示例:

  const SayHi = {
    a: (v) => `${v} a`,
    b: (v) => `${v} b`,
    c: (v) => `${v} c`,
  };

  // 优化前 =====================================
  const Controller = {
    a(v) {
      return SayHi.a(v);
    },
    b(v) {
      return SayHi.b(v);
    },
    c(v) {
      return SayHi.c(v);
    },
  };

  console.log(Controller.a("hi~")); // hi~ a

  // 优化后 =====================================
  const Controller = {
    a: SayHi.a, // 这里是把一个方法赋值给另一个方法,不是方法的调用
    b: SayHi.b,
    c: SayHi.c,
  };
  console.log(Controller.a("hi~")); // hi~ a

2. 传递一个函数作为参数

  • 头等函数中-函数当作值或者说是变量: 下面代码片段中: callback() 函数作为 sayHi() 函数的参数。
  function callback() {
    return "Hello, ";
  }
  function sayHi(callback, name) {
    console.log(callback() + name);
  }
  // 传递 `callback` 作为 `sayHi` 函数的参数
  sayHi(callback, "wuyanfeiying!"); // Hello, wuyanfeiying!

补充:回调函数

  • 我们把一个函数作为参数传递给另外一个函数,那么我们就称这个函数为回调函数。sayHi() 函数就是一个回调函数
  • 回调与同步、异步并没有直接的联系,回调只是一种实现方式,既可以有同步回调,也可以有异步回调,还可以有事件处理回调和延迟函数回调,这些在我们工作中有很多的使用场景。

3. 返回一个函数

函数可被作为来对待,以下示例中,sayHi()返回一个匿名函数,有两种调用的方式:

  • 方式一:用一个变量先接受sayHi()返回的值, 之后再调用它里面被返回的函数
  • 方式二:使用双括号 ()() 来调用 sayHi() 返回的函数
  function sayHi() {
    // 返回一个匿名函数
    return function () {
      console.log("Hi~");
    };
  }
  // 方式一:
  const foo = sayHi();
  foo(); // Hi~

  // 方式二
  sayHi()(); // Hi~

补充:匿名函数

  function(){
  // ...
  }();

  • 通过匿名函数可以实现闭包
    • 闭包是可以访问在函数作用域内定义的变量的函数。若要创建一个闭包,往往都需要用到匿名函数。
  • 模拟块级作用域,减少全局变量。执行完匿名函数,存储在内存中相对应的变量会被销毁,从而节省内存。

补充: 高阶函数(Higher-Order Function)

  • 一个返回另外一个函数的函数被称为高阶函数。
  • 编写高阶函数,就是让函数的参数能够接收别的函数。
  • JS中常见的三种高阶函数:map()reduce()filter()

小结

总之,在JavaScript中,函数没什么特别之处,和JS中的任何其他数据类型一样,我们可以把函数赋值给变量或存储到数组中,还可以作为另一个函数的参数和返回值,甚至我们可以在程序运行的时候通过new Function()来构造一个新的函数。

附录