一等公民定义

在很多技术文档和博客里面,我们都会看到像一等公民这样的字眼。在使用 JavaScript 时听说函数是一等公民,使用 React 的时候说组件是一等公民。那到底什么是一等公民呢,这个一等公民到底有什么特性或者说怎样才算得上是一等公民?接着往下看吧!

In _programming language design, a first-class citizen (also type, object, entity, orvalue) in a given programming language is an entity which supports all the operationsgenerally available to other entities. These operations typically include being passedas an argument, returned from a function, and assigned to a variable.

一等公民,英文全称 “First-Class Citizen”。上面对一等公民的一串英文解释来自维基百科,大致的意思就是说:在程序语言设计中,一等公民(包括类型,对象,实体或值)在一个给定的编程语言中是一个支持其他实体所有操作的实体。 这些操作通常包括作为参数传递,从函数中返回,分配给变量。

简单一点就是说:如果某程序设计语言中的一个类型,对象,实体或值可以作为参数传递,也可以从子程序中返回,还可以赋值给变量,那么就称它为一等公民

一等公民体现

针对 JavaScript 中函数一等公民的体现,我们对照着上面的一等公民定义里面的特性,一点一点的来说。

  • 1、可以赋值给变量

这一点,我们在上面函数的定义里面已经提到了。第二种定义函数的方式中,我们声明了一个匿名的函数表达式,然后将函数表达式赋值给了 myFunc 变量,然后我们如果需要调用该函数,直接执行 myFunc(arguments) 即可。所以,这一点完全符合。

  1. // 声明一个匿名函数,并将函数赋值给 myFunc 变量
  2. const myFunc = function(arguments) {}
  3. // 调用函数
  4. myFunc(arguments);
  • 2、可以作为参数传递

其实,函数可以作为参数传递这一特性,在我们实际项目开发中的代码是随处可见的,例如以下函数使用方式:

  1. // 声明一个匿名函数,并将函数赋值给 myFunc 变量
  2. const myFunc = function(arguments, callback) {
  3. // do something
  4. callback();
  5. }
  6. // 调用函数,我们在传入其他参数的同时,传入 callback 函数
  7. myFunc(arguments, callback);

看到这里,你可以回想一下或者直接去你的项目中看一下代码,应该很容易就找到这种形式的代码了。

在实例代码中,函数接受其他参数的同时,还接受一个 callback 函数,这个函数在 myFunc 函数执行一定的逻辑后再被调用。实际的 myFunc 函数调用时,传入的参数和接受的参数顺序一致就好了。这些大家应该都知道,这就是我们后续要讲解到的回调函数和高阶函数的一种了,在这里我就不啰嗦了!

接着看下一个特性!

  • 3、可以从子程序中返回
  1. // 声明一个匿名函数,并将函数赋值给 myFunc 变量
  2. const myFunc = function(arguments) {
  3. // do something
  4. return function() {
  5. // do something
  6. }
  7. }
  8. // 调用函数
  9. const result1 = myFunc(arguments);
  10. result1();

想必大家对上面实例代码都不陌生了吧!

首先,我们声明了一个匿名函数,然后将函数赋值给了 myFunc 变量。在函数的逻辑里面,我们最后返回了一个新的匿名函数。在实际执行 myFunc() 调用外层定义的匿名函数时,会返回一个新的函数,也就是

  1. // 调用函数
  2. const result1 = myFunc(arguments); ===> var result1 = function() { // do something }

此时,我们调用result1() 就会得到最终的结果。这种形式的函数也就是我们后续要详细讲解的高阶函数的一种了。

说到这里,JavaScript 函数的一等公民或一等函数的特性就展露无遗了。正是因为函数一等公民的特性,才给我们带来了很多函数编程的模式,例如高阶函数、函数柯里化等等,让我们开发起来更加的得心应手。

拓展知识

1、二等公民:可以作为参数传递,但是不能从子程序中返回,也不能赋给变量。

2、三等公民:它的值连作为参数传递都不行。

3、在很多传统语言(例如 C/C++/Java/C# 等)中,函数都是作为二等公民存在的。你只能用语言的关键字声明一个函数,然后调用它。如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为返回值,就需要通过函数指针(function pointer)、代理(delegate)等特殊的方式周折一番。