Node.js 高阶函数

立即执行函数

我们可以立即执行一个函数,在定义它之后。只需将函数包裹在括号()中并调用它。

  1. (function myData() {
  2. console.log("myData was executed!");
  3. })();

立即执行的函数创建一个新的变量作用域。if,else或while不会在JavaScript中创建新的变量作用域。

  1. var myData = 123;
  2. if (true) {
  3. var myData = 456;
  4. }
  5. console.log(myData); // 456;

在JavaScript中创建新的变量作用域的唯一推荐方法是使用函数。下面的代码显示了如何使用立即执行的函数创建一个新的变量范围。

  1. var myData = 123;
  2. if (true) {
  3. (function () { // create a new scope
  4. var myData = 456;
  5. })();
  6. }
  7. console.log(myData); // 123;

匿名函数

没有名称的函数称为匿名函数。在JavaScript中,可以将函数分配给变量。如果你要使用一个函数作为一个变量,你不需要命名该函数。

下面的代码显示了两个定义函数内联的方法。这两种方法都是等效的。

  1. var foo1 = function namedFunction() {
  2. console.log("foo1");
  3. }
  4. foo1(); // foo1
  5. var foo2 = function () { // no function name i.e. anonymous function
  6. console.log("foo2");
  7. }
  8. foo2(); // foo2

如果一个函数的处理方式与语言中任何其他变量的处理方式相同,那这种编程语言被称为具有一流功能。而JavaScript具有一流的功能。

高阶函数

由于JavaScript允许我们为变量赋值函数,我们可以将函数传递给其他函数。将函数作为参数的函数称为高阶函数。高阶函数的一个非常常见的例子是setTimeout。

以下代码显示如何使用setTimeout函数。

  1. setTimeout(function () {
  2. console.log("2000 milliseconds have passed since this demo started");
  3. }, 2000);

如果在Node.js中运行此应用程序,你会在两秒后看到console.log消息然后应用程序将退出。我们使用一个匿名函数作为setTimeout的第一个参数。这使得setTimeout是一个高阶函数。我们可以创建一个函数并传入。

  1. function foo() {
  2. console.log("2000 milliseconds have passed since this demo started");
  3. }
  4. setTimeout(foo, 2000);

Closure

如果在另一个函数内定义了一个函数,内部函数可以访问在外部函数中声明的变量。外部函数中的变量已经被内部函数关闭。这个概念本身是足够简单和直观的。

  1. function outerFunction(arg) {
  2. var variableInOuterFunction = arg;
  3. function myValue() {
  4. console.log(variableInOuterFunction);
  5. }
  6. myValue();
  7. }
  8. outerFunction("hello closure!"); // logs hello closure!

内部函数可以从外部范围访问变量,即使在外部函数已返回时。因为变量仍然在内部函数中绑定,而不依赖于外部函数。

  1. function outerFunction(arg) {
  2. var variableInOuterFunction = arg;
  3. return function () {
  4. console.log(variableInOuterFunction);
  5. }
  6. }
  7. var innerFunction = outerFunction("hello closure!");
  8. innerFunction();