📜  js 闭包 - Javascript (1)

📅  最后修改于: 2023-12-03 14:43:33.663000             🧑  作者: Mango

JavaScript 闭包(Closures)

在 JavaScript 中,闭包是一种特殊的函数,它可以访问其外部环境中定义的变量和函数,即使外部环境已经不存在了也能够访问它们。闭包经常被用来模拟私有变量和创建模块化代码。

创建闭包

要创建一个闭包,只需要在函数内部定义一个另一个函数,后者可以访问外部函数的变量和参数。例如:

function outerFunction() {
  const outerValue = 'I am outside!';

  function innerFunction() {
    console.log(outerValue);
  }

  return innerFunction;
}

const inner = outerFunction();
inner(); // 输出 'I am outside!'

在这个例子中,outerFunction 内部定义了一个名为 innerFunction 的函数,该函数在其外部函数中声明的变量 outerValue 上创建了一个闭包。当 outerFunction 返回 innerFunction 时,innerFunction 仍然可以访问 outerValue,并在调用 inner() 时能够成功将其输出。

模拟私有变量

因为闭包可以访问其外部函数中变量的值,所以可以用它们来模拟一种私有变量的行为。例如:

function counter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const incrementCounter = counter();
incrementCounter(); // 输出 '1'
incrementCounter(); // 输出 '2'

在这个例子中,counter 函数返回一个内部函数,该内部函数可以访问并修改 count 变量。由于该变量只是在 counter 函数作用域内声明的,因此外部函数无法访问它,它实际上是一个“私有”变量。

创建模块化代码

另一个闭包的常见用途是创建模块化代码。通过创建一个闭包,可以将一组函数和变量捆绑在一起,从而形成一个封闭的块,使其能够访问其中的内容,但不会对外部环境产生任何影响。例如:

const myModule = (function() {
  let privateVariable = 'I am private!';

  function privateMethod() {
    console.log('This is private!');
  }

  function publicMethod() {
    console.log('This is public!');
  }

  return {
    publicMethod: publicMethod
  };
})();

myModule.publicMethod(); // 输出 'This is public!'
myModule.privateMethod(); // TypeError: myModule.privateMethod is not a function

在这个例子中,我们首先创建了一个立即调用的函数表达式(IIFE),该表达式返回一个包含公共方法的对象。该对象中的函数和变量可以在闭包外部进行访问,但无法访问私有变量和私有方法。

总结

闭包是一个强大的 JavaScript 特性,可以用于访问外部变量,并创建私有变量和模块化代码。当不正确地使用闭包时,可能会导致内存泄漏和性能问题,因此应该避免在循环中使用它们。但是,如果正确地使用它们,闭包可以成为一种强大的工具,用于创建高度可组合、易维护的代码。