如何使用闭包在JavaScript中创建一个私有计数器
闭包是将一个函数与对其外部状态(词法环境)的引用捆绑在一起的组合。换句话说,闭包允许您从内部函数访问外部函数的作用域。
例如:在这里内部函数与外部函数形成了闭包。可以将 str 变量称为私有成员,我们可以访问其值,但不能直接修改。
Javascript
<script>
function outer() {
let str = "GeeksforGeeks";
function inner() {
console.log(str);
}
return inner;
}
const fun = outer();
fun();
</script>
输出:
GeeksforGeeks
私有计数器的概念意味着我们无法直接在公共/全局范围内修改计数器变量。下面的逐步指南将教你如何使用闭包实现私有计数器并理解其工作原理。
步骤1: 创建 counter.js 和 index.html 文件。你可以为这些文件取任何合法的名称。
步骤2: 首先从 index.html 文件开始,并创建一个前端来查看计数器。我们将创建一个
<
div>来显示计数器的值,并创建两个按钮,一个用于递增计数器,另一个用于递减计数器。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- counter.js becomes available
at execution time-->
<script src="counter.js"></script>
</head>
<body>
<h1 style="color: blue;">
Private Counter using Closure
</h1>
<!-- This div displays the value of
private counter-->
<div id="counter_div" style=
"margin-left: 5%; color: red;">
<!-- Default value of counter is zero-->
<h2>0</h2>
</div>
<!-- Buttons for incrementing and
decrementing the value of private counter-->
<button onclick="counterHandler(this)"
value="1">
Increment
</button>
<button onclick="counterHandler(this)"
value="0">
Decrement
</button>
</body>
</html>
在这里,我们使用位于JavaScript文件中的counterHandler函数来处理按钮的点击。按钮的值帮助我们区分哪个按钮被点击了。还有一个id为div的元素,我们可以使用它来从JavaScript代码中进行更新。
步骤3: 让我们现在对counter.js文件进行处理,并实现后台功能。
counter.js
// Global function which would form
// closure with modify function
function counter() {
// Private counter variable
let count = 0;
// To increment the value of counter
function increment() {
count++;
}
// To decrement the value of counter
function decrement() {
count--;
}
// Modify function forms closure
// here which is used outside
function modify(val) {
// To check increment or decrement
// button has been clicked
if (val === "1") increment();
else if (val === "0") decrement();
// Return the counter
return count;
}
// Returning to make it available
// outside counter function
return modify;
}
// Storing the closure modify
const closure = counter();
// This function handles the button
// click, objButton to get value
function counterHandler(objButton) {
// Storing the value return by modify
let count = closure(objButton.value);
// Getting div by it's id
// and modifying its inner html
document.getElementById("counter_div")
.innerHTML = "<h2>" + count + "</h2>";
}
当按钮被点击时, counterHandler 被调用,我们从 objButton 对象中获取按钮的值。如果值为一(1),则增加计数器的值;否则减少计数器的值,计数器的变量名为 count 。
在 counter 函数中,我们有一个计数器变量 count , increment 函数用于增加计数器的值, decrement 函数用于减少计数器的值。当 counter 函数被调用时,返回一个闭包作为全局变量,并将其实例存储在 closure 常量中。
最后,使用闭包的 innerHTML 属性将div的内容修改为闭包返回的计数器的值。
步骤4: 复制HTML index.html 文件的完整路径,并粘贴到任何浏览器中。在浏览器加载HTML文件后,你会看到类似的内容。现在点击 增加 和 减少 按钮,并观察计数器的值的变化。

现在让我们看看在单击按钮时后端使用开发者工具会发生什么。在下面的图像中,我们将计数器的值设为-1,以查看作用域的定义和与之相关的情况。
这是如何在JavaScript中使用闭包实现私有计数器变量的方法。闭包提供了在JavaScript中实现数据封装功能的方式。
参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
极客教程