为何我的JavaScript函数不具备变量的作用域?
关于JavaScript作用域与闭包的问题解答
兄弟,我一眼就看出问题所在了——你代码里的total是直接声明在全局作用域里的,这就导致你的increment函数根本没有自己的局部作用域变量可以操作,自然体现不出作用域的隔离性啦!
先分析你当前代码的问题
你现在的total是全局变量,整个页面的所有脚本都能直接访问和修改它,increment函数只是在操作这个全局变量而已,完全没有用到局部作用域的特性。比如随便在控制台敲total = 100,你的计数器就直接被改了,这显然不是你想要的“有作用域”的效果。
用闭包实现带私有作用域的计数器
要让函数拥有自己的私有变量,同时能持续维护这个变量的状态,闭包就是最适合的方案。这里给你改个示例:
修改后的app.js代码:
// 用立即执行函数表达式(IIFE)创建私有作用域 const counterModule = (function() { // 这个total是局部变量,只有内部函数能访问,外部碰不到 let total = 0; // 定义increment函数,它会形成闭包,保留对total的引用 function increment() { total += 1; // 补充完整更新DOM的代码 document.getElementById('number').textContent = total; } // 把需要暴露给外部的方法返回出去 return { increment: increment }; })();
对应的index.html按钮修改:
<button onclick="counterModule.increment();">点击计数</button> <h2 id="number">0</h2>
为啥这样就有作用域了?
total现在被包裹在IIFE的局部作用域里,外部代码(比如控制台、其他脚本)根本无法直接访问或修改它,实现了变量的私有性。increment函数作为内部函数,即使IIFE执行完毕,它依然能保留对total的引用(这就是闭包的核心),每次点击按钮调用它时,都会更新这个私有变量的状态,同时把结果渲染到页面上。
额外提个ES6的简化写法
如果你用ES6+的语法,也可以用块级作用域结合闭包来写,更简洁:
let counterModule = (() => { let total = 0; return { increment: () => { total++; document.getElementById('number').textContent = total; } }; })();
这样改造后,你的计数器就拥有了自己的独立作用域,变量total不会被全局污染,完美解决你的疑问~
内容的提问来源于stack exchange,提问作者Aid19801
相关产品推荐
相关产品推荐

