javascript可通过属性描述符控制属性的可读、可写、可枚举和可配置性;常用object.defineproperty设writable和configurable为false实现只读不可删,或用get/set实现带校验逻辑的受控访问。

JavaScript 中可以通过属性描述符(Property Descriptor)控制对象属性的可读性、可写性、可枚举性和可配置性,从而实现“受保护”的访问效果——不是绝对私有,但能防止意外修改或遍历。
使用 Object.defineProperty 设置不可写、不可配置属性
这是最常用的方式:将 writable 设为 false,configurable 设为 false,就能让属性值无法被重新赋值,也不能被删除或重新定义。
-
writable: false→ 赋值操作会被静默忽略(非严格模式)或抛出 TypeError(严格模式) -
configurable: false→ 不能再用defineProperty修改该属性的描述符,也不能用delete删除它 - 注意:
configurable: false时,writable只能从true改为false,不能反向操作
const obj = {};
Object.defineProperty(obj, 'PI', {
value: 3.14159,
writable: false,
enumerable: false,
configurable: false
});
obj.PI = 3; // 无效(非严格模式)或报错(严格模式)
delete obj.PI; // 失败
console.log(obj.PI); // 3.14159
用 get/set 描述符实现带逻辑的受控访问
当需要在读写时插入校验、日志、转换等逻辑时,应使用 get 和 set 描述符。此时 value 和 writable 不可用,二者互斥。
-
get函数在读取属性时自动调用,返回值即为属性值 -
set函数在赋值时触发,接收新值作为参数,可用于拦截、过滤或拒绝非法写入 - 这类属性默认
enumerable和configurable都为false,需显式设置才可枚举或重配置
const user = {};
let _age = 25;
Object.defineProperty(user, 'age', {
get() { return _age; },
set(value) {
if (typeof value === 'number' && value >= 0 && value
<h3>批量定义:用 <strong>Object.defineProperties</strong> 管理多个受保护属性</h3>
<p>当对象需要多个受保护属性时,避免重复调用 <code>defineProperty</code>,改用 <code>defineProperties</code> 一次性声明。</p>
- 传入目标对象和一个属性描述符键值对的对象
- 每个键对应一个属性名,值是其完整的描述符配置
- 适合初始化阶段集中管控访问权限
const config = {};
Object.defineProperties(config, {
API_URL: { value: 'https://api.example.com', writable: false, configurable: false },
TIMEOUT: { value: 5000, writable: false, configurable: false },
DEBUG: {
get() { return window.DEBUG_MODE; },
set(v) { window.DEBUG_MODE = Boolean(v); }
}
});
与 class 结合:在构造函数或原型上定义受保护成员
ES6 class 本身不支持直接在字段声明中使用描述符,但可在构造函数内或类外部用 Object.defineProperty 补充定义。
- 在实例上定义(如
constructor中)→ 每个实例独有,适合封装私有状态 - 在原型上定义(如
Object.defineProperty(MyClass.prototype, ...))→ 所有实例共享,适合只读常量或统一访问逻辑 - 注意:不能在 class 字段语法(
field = value)中使用描述符,那是普通赋值
class Counter {
constructor() {
this._count = 0;
Object.defineProperty(this, 'count', {
get() { return this._count; },
set(value) {
if (Number.isInteger(value) && value >= 0) {
this._count = value;
}
},
enumerable: true
});
}
}Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











