JavaScript闭包入门问题:为何计数器函数未按预期工作?
问题分析与解决
你的代码没达到预期效果,核心是对闭包的执行时机和状态保存逻辑理解有偏差,我来帮你拆解清楚:
1. 核心问题出在哪
(1)逻辑执行时机错了
当你执行let shopping = counter();时,没有传入key参数,函数内部的两个if判断根本不会触发,counter保持初始值10。而且这两个判断是在创建返回函数的那一刻执行一次,不是每次调用shopping时都执行。
(2)返回的函数没处理参数
你返回的匿名函数根本没有接收key参数,所以后面调用shopping('milk')时,传的参数完全没被用到,自然不会修改counter的值。
(3)闭包的状态没被正确利用
你想让shopping持续保存counter的状态,但现在返回的函数只是固定打印第一次创建时的counter值(也就是10),没有把修改逻辑放到返回的函数内部。
修正后的代码
把修改counter的逻辑放到返回的函数里,让它接收key参数,这样每次调用shopping时都会更新闭包保存的状态:
let counter = () => { // 这个counter变量会被闭包永久保存,不会重复初始化 let counter = 10; // 返回的函数接收key参数,每次调用时处理计数逻辑 return function(key) { if (key === 'milk') { ++counter; } if (key === 'bread') { --counter; } console.log(counter); } } let shopping = counter(); shopping('milk'); // 输出11 shopping('milk'); // 输出12 shopping('bread'); // 输出11 shopping('bread'); // 输出10
为什么这样就生效了?
- 当你调用
counter()时,会创建一个局部变量counter(初始值10),然后返回一个内部函数。这个内部函数会捕获并保留对counter变量的引用——这就是闭包的核心作用,让函数能访问并修改外部作用域的变量。 - 每次调用
shopping(key)时,都会执行内部函数里的逻辑,根据传入的key更新闭包保存的counter值,然后打印最新状态。 - 因为
counter是在counter()的局部作用域里,不会被外部代码污染,也不会在每次调用shopping时重新初始化,所以状态能持续保留下来。
内容的提问来源于stack exchange,提问作者Jenny
相关产品推荐
相关产品推荐

