跳转到内容

JavaScript/闭包

来自维基教科书,开放的书籍,用于开放的世界



闭包是一种技术,其中函数与其周围变量(词法环境)捆绑在一起(封装)。 通常,闭包是在像 JavaScript 这样的函数式编程语言中实现的,它们支持柯里化

词法环境

[编辑 | 编辑源代码]

首先,我们展示函数对其词法环境的访问。 仅此而已不是一个闭包

"use strict";

function incrementByCertainValue(param) {
  return param + certainValue;
}

let certainValue = 10;
alert(incrementByCertainValue(8)); // 18

certainValue = 100;
alert(incrementByCertainValue(8)); // 108

函数incrementByCertainValue将其参数增加certainValue变量的值。 因为incrementByCertainValue以及certainValue是在同一个块内定义的,所以函数可以访问该变量。 每当调用该函数时,它都会读取该变量并使用它来计算其返回值。

为了将上面的例子扩展到闭包,我们必须将一个(内部)函数与访问其词法环境的变量(通常是另一个函数)结合起来,并且通过返回这个内部函数来保存这种状态。

"use strict";

function incrementByCertainValue(param) {
  // declare a function that will perform the work. (Only declaration, currently not invoked.)
  const add = function (certainValue) {
    // access to 'param' from lexical environment and to its parameter 'certainValue'
    return param + certainValue;
  }
  return add;
}

const incrementByFive = incrementByCertainValue(5);
alert(incrementByFive(8));  // 13

const incrementBySix = incrementByCertainValue(6);
alert(incrementBySix(8));   // 14

alert(incrementByFive(10)); // 15

(外部)函数incrementByCertainValue

包含一个参数param
定义一个(内部)函数add,它接受另一个参数certainValue
除了其参数之外,(内部)函数还可以访问其词法环境,其中定义了param
返回(内部)函数。

到目前为止,只有声明,没有运行代码。

当变量incrementByFive在第 12 行声明时,它被初始化为函数incrementByCertainValue(5)的返回值。 这是关键点代码运行和闭包技术起作用的地方。 在incrementByCertainValue中,5 被称为参数/变量param。 接下来,函数add使用来自其词法环境的param创建。 此函数add接受一个参数,该参数必须稍后从调用例程中提供。 incrementByCertainValue的返回语句提供此函数add,该函数已将值“5”绑定到其主体中。 请注意,函数名称add是任意的,在incrementByCertainValue之外看不到。

incrementByCertainValue第二次使用参数“6”调用时,“6”将绑定到一个单独的第二个函数。

... 在另一个页面上提供(点击此处)。

另请参阅

[编辑 | 编辑源代码]
华夏公益教科书