全局变量不是垃圾桶
写代码的时候,图省事把变量全扔到全局作用域里,好像挺方便。函数里想用就用,不用传参也不用返回,多轻松。可项目一大,这种“方便”就成了定时炸弹。
想象一下,你和同事一起开发一个网页功能,他改了一个叫 userCount 的全局变量,你完全不知道这事儿。结果你写的统计逻辑突然出错,查半天才发现这变量在别处被悄悄改了。这种“背锅”场景,在团队协作中太常见了。
全局变量为啥容易出问题
全局变量在整个程序生命周期内都能被访问和修改,谁都能动它。一旦多个函数都依赖或修改同一个全局变量,它们之间就产生了隐式耦合。改一处,可能影响八处。调试时就像在黑屋子里找猫,根本不知道哪个函数动了数据。
比如下面这段 JavaScript 代码:
let userName = '小明';
function greet() {
console.log('你好,' + userName);
}
function updateName(newName) {
userName = newName;
}
updateName('小红');
greet(); // 输出:你好,小红看起来没啥问题,但如果 updateName 被其他地方误调,或者有多个类似函数同时操作 userName,那结果就不可控了。
用局部作用域保护数据
把变量关进“小房间”,只有该用的人才能进去。函数内部声明的变量,外界看不见,自然就不会被乱改。
还是上面的例子,改成这样更安全:
function greet(userName) {
console.log('你好,' + userName);
}
function updateAndGreet(newName) {
const currentName = newName;
greet(currentName);
}
updateAndGreet('小红'); // 输出:你好,小红现在 currentName 只在函数内部有效,不会干扰其他逻辑。数据流动清晰,谁调用、谁负责,一目了然。
模块化是好习惯
现代开发提倡模块化。每个文件管自己的事,通过明确的接口(比如函数参数、导出方法)和其他部分通信。Node.js、ES6 模块、甚至简单的 IIFE(立即执行函数)都能帮你隔离作用域。
比如用 IIFE 把相关逻辑包起来:
const userModule = (function() {
let userName = '小明';
function greet() {
console.log('你好,' + userName);
}
function setName(newName) {
userName = newName;
}
return {
greet,
setName
};
})();
userModule.setName('小李');
userModule.greet(); // 输出:你好,小李外面看不到 userName,只能通过提供的方法操作,数据私有了,安全性高了。
写代码不是赶工完事,而是让别人(包括几个月后的自己)能看懂、敢改、不怕崩。少用全局变量,多用参数传递和模块封装,项目越大,越能体会到这种习惯的好处。