JavaScript中闭包是实现私有变量最经典的方式,通过外层函数声明变量并返回含Getter/Setter的对象,使变量被内层函数引用而“私有化”;支持数据校验、Object.freeze冻结或class#private字段增强封装性。

JavaScript 中闭包是实现私有变量最经典的方式,通过函数作用域“捕获”变量,外部无法直接访问,只能通过返回的 Getter 和 Setter 函数间接操作。
用闭包封装私有变量
定义一个外层函数,在其内部声明变量(如 value),再返回一个对象,该对象包含访问和修改这个变量的方法。由于外层函数执行后变量仍被内层函数引用,就形成了闭包,变量被“私有化”。
示例:
function createCounter() {
let count = 0; // 私有变量,外部不可直接访问
return {
getCount() { return count; }, // Getter
setCount(newVal) { count = newVal; }, // Setter
increment() { count++; }
};
}
const counter = createCounter();
console.log(counter.getCount()); // 0
counter.setCount(5);
console.log(counter.getCount()); // 5
console.log(counter.count); // undefined(无法直接访问)
支持数据校验的 Setter
Setter 不只是赋值,还可以加入类型检查、范围限制等逻辑,增强健壮性。
立即学习“Java免费学习笔记(深入)”;
例如限制 count 只能为非负整数:
function createBoundedCounter() {
let count = 0;
return {
getCount() { return count; },
setCount(newVal) {
if (typeof newVal === 'number' && newVal >= 0 && Number.isInteger(newVal)) {
count = newVal;
} else {
throw new Error('count must be a non-negative integer');
}
}
};
}
避免意外覆盖 Getter/Setter
直接返回的对象方法可被外部重写(比如 counter.getCount = null),若需更强封装,可用 Object.freeze() 冻结返回对象,或改用 class + #private field(ES2022+)作为现代替代方案。
冻结示例:
function createFrozenCounter() {
let count = 0;
return Object.freeze({
getCount() { return count; },
setCount(newVal) { count = newVal; }
});
}
多个私有变量的管理
一个闭包可维护多个私有变量,各 Getter/Setter 按需组合,保持逻辑内聚。
例如同时管理用户名和邮箱:
function createUserProfile() {
let name = '';
let email = '';
return {
getName() { return name; },
setName(val) { name = String(val).trim(); },
getEmail() { return email; },
setEmail(val) {
if (/^\S+@\S+\.\S+$/.test(val)) email = val;
else throw new Error('Invalid email format');
}
};
}


















