发布于 2026-01-06 4 阅读
0

JavaScript 中的闭包——最简单的解释

JavaScript 中的闭包——最简单的解释

JavaScript 中的闭包就像函数的秘密通道,即使函数运行完毕,也能记住某些变量。在本文中,我将尝试用最简单的方式回答“JavaScript 闭包是如何工作的?”这个问题,以便您能立即上手使用它们。

在继续之前,我想邀请您访问 0dev,这是一个支持自然语言的开源数据平台。使用 0dev,您可以无需复杂的 SQL 查询即可访问数据,无需任何编码即可进行可视化,并且无需任何数据科学经验即可获得洞见。

代码仓库:https://github.com/0dev-hq/0dev


假设你想创建一个简单的计数器,但你不希望代码的其他部分修改计数器的内部数值。你可以创建一个函数,该函数返回一个对象,该对象包含可以修改内部数值的方法,但只有该函数知道这些方法。以下是一个示例:

function counter() {
  let count = 0;

  return {
    increment: function() {
      count++;
    },
    decrement: function() {
      count--;
    },
    getCount: function() {
      return count;
    }
  };
}

let myCounter = counter();
console.log(myCounter.getCount()); // 0
myCounter.increment();
console.log(myCounter.getCount()); // 1
Enter fullscreen mode Exit fullscreen mode

在我们的示例中,可以说该counter函数返回一个具有三个方法的对象:increment,,decrementgetCount

这些方法都可以访问count父函数中定义的变量counter。但是,由于父counter函数已经执行完毕,因此count无法从全局作用域直接访问该变量,而内部函数仍然可以访问它。

换句话说,返回的对象及其方法是闭包,可以访问该count变量。

所以,这是闭包的一个常见用例,现在让我们来看另一个例子。

闭包的另一个常见用途是创建一个函数,我们想将其作为回调函数传递,并保持对其父作用域中变量的访问。例如,请看以下代码:

function createFullName(firstName) {
  return function(lastName) {
    return firstName + " " + lastName;
  };
}

let myFullName = createFullName("John");
console.log(myFullName("Doe")); // "John Doe"
console.log(myFullName("Smith")); // "John Smith"
Enter fullscreen mode Exit fullscreen mode

在这个过于简化的例子中,我们有一个函数createFullName,它接受一个人的名字作为参数,并返回一个新函数,该新函数本身接受一个人的姓氏作为参数,并返回全名。

内部函数是一个闭包,因为它“封闭”了 firstName 变量并将其保留下来,即使父函数已经运行完毕。例如,在用户需要在两个不同的输入框中填写名字和姓氏的表单中,这非常有用。

这项技术也是 JavaScript 函数式编程的基本原理之一。

您能否补充其他使用案例或示例?

文章来源:https://dev.to/mohsenkamrani/closures-in-javascript-the-simplest-explanation-9gj