JS闭包

70 阅读2分钟

closure.png

理解闭包

在 JavaScript 中,垃圾回收机制在函数执行完毕后会销毁函数的局部变量以释放内存空间。这意味着函数内部的变量在函数执行结束后将不再可用,并且它们所占据的内存将被垃圾回收机制回收。

然而,当需要访问函数执行后的变量时,如果没有闭包存在,我们只能通过全局变量的方式来实现。这种方式容易引起命名冲突和意外修改,因为全局变量对于整个应用程序是可见的。

闭包的存在解决了这个问题,它允许函数在执行完毕后,仍然可以访问和操作函数定义时的词法环境中的变量。闭包使得这些变量成为私有数据,对外部是不可见的。通过闭包,函数可以创建一个封闭的作用域,保护内部变量不受外部干扰,并且可以在函数执行后继续使用这些变量

闭包还有其他一些优点,包括在某些情况下可以提高性能,避免重复计算,以及允许函数记住之前的操作或计算结果。

需要注意的是,闭包引用的变量如果占用大量内存,并且在后续的执行过程中不再需要使用,可能会导致内存泄漏的问题。因此,在使用闭包时,需要合理管理内存,确保只保留必要的引用,并在不再需要时释放闭包

案例说明

function createCounter() {
  let count = 0;
  function increment() {
    count++;
    console.log(count);
  }
  return increment;
}
const counter = createCounter();
counter(); // 输出: 1
counter(); // 输出: 2

在这个例子中,createCounter 函数创建了一个计数器,并返回一个内部函数 increment。 increment 函数引用了外部函数 createCounter 的词法环境中的变量 count。 当我们调用 createCounter 函数时,它会返回 increment 函数。我们将这个返回的函数赋值给变量 counter。此时,counter 变量持有了 increment 函数和它的词法环境。 每次调用 counter 函数时,它会增加 count 变量的值,并将结果打印到控制台上。由于 counter 函数形成了闭包,它仍然保持着对外部环境中的 count 变量的引用。因此,即使 createCounter 函数已经执行完毕,count 变量不会被销毁,而是在每次调用 counter 函数时被更新和访问。