跳转到主要内容
模块 4 · 第 4 课(共 4)课程中的16/32~12 min
模块课程(4/4)

关闭和范围

闭包是一个“记住”定义它的范围的变量的函数, 即使该范围结束后。它看起来很神奇,但它是范围规则的直接结果。

范围链

函数可以读取在其自身外部声明的变量,沿着作用域链向上移动:

JS
const moltiplicatore = 10;

function moltiplicaPer10(n) {
  return n * moltiplicatore; // reads from the closure
}

moltiplicaPer10(3); // 30

函数工厂

最典型的模式:一个函数返回另一个函数,用 它收到的参数。

JS
function creaSaluto(prefisso) {
  return function (nome) {
    return `${prefisso}, ${nome}!`;
  };
}

const ciao = creaSaluto('Ciao');
const buongiorno = creaSaluto('Buongiorno');

ciao('Anna'); // 'Ciao, Anna!'
buongiorno('Marco'); // 'Buongiorno, Marco!'

每次调用 creaSaluto 都会创建一个 单独的 作用域,并具有自己的 prefisso。

与私人国家的柜台

经典的例子:一个封闭的柜台,可以保留柜台而不将其暴露在外面。

JS
function creaContatore() {
  let n = 0;
  return function () {
    n++;
    return n;
  };
}

const c = creaContatore();
c(); // 1
c(); // 2
c(); // 3

const c2 = creaContatore();
c2(); // 1  ← isolated state!

n 是私有:闭包之外的任何人都无法读取或修改它。

尝试一下

锻炼#js.m4.l4.e1
尝试:0加载中...

实现一个返回函数的工厂`makeCounter()`:该函数的每次调用都返回一个从1开始的渐进整数。不同的计数器必须是独立的。

正在加载编辑器...
显示提示

在 makeCounter 中用 let 声明 n,然后返回一个执行 ++n 的函数。

3 次尝试后可用的解决方案

复习练习

锻炼#js.m4.l4.e2
尝试:0加载中...

实现返回一个函数的 makeAdderWith(base) :给定数字 n,它返回 base + n。每个加法器都会记住自己的基数。

正在加载编辑器...
显示提示

返回一个使用外部参数的基数的箭头函数。

3 次尝试后可用的解决方案