javascript中可通过getter/setter拦截属性读写:object.defineproperty适用于普通对象单属性,class中可用语法糖实现更简洁的封装,二者均支持逻辑校验与副作用控制。

JavaScript 中通过 getter 和 setter 可以在访问或修改对象属性时插入自定义逻辑,实现对属性读写操作的拦截和控制。
用 Object.defineProperty 定义 getter/setter
这是最基础、兼容性最好的方式,适用于普通对象的单个属性:
- 使用
Object.defineProperty(obj, prop, descriptor),其中descriptor包含get和/或set函数 -
get函数在读取属性时自动调用,应返回值;set函数在赋值时调用,接收新值作为参数 - 不能同时设置
value/writable和get/set,二者互斥
示例:
const obj = {};
let _name = 'Alice';
Object.defineProperty(obj, 'name', {
get() {
console.log('读取 name');
return _name;
},
set(value) {
console.log('设置 name 为:', value);
if (typeof value === 'string' && value.trim()) {
_name = value.trim();
} else {
throw new Error('name 必须是非空字符串');
}
}
});
console.log(obj.name); // 输出:读取 name → "Alice"
obj.name = ' Bob '; // 输出:设置 name 为: " Bob " → 内部存为 "Bob"
在 class 中使用 getter/setter 语法糖
ES6+ 的 class 支持更简洁的声明式写法,语义清晰,适合封装实例属性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
get propName() { ... }定义只读行为(无参数) -
set propName(value) { ... }定义写入逻辑(必须且仅有一个参数) - 它们本质上也是通过 defineProperty 实现的,但更易读、支持继承
示例:
class Person {
constructor(age) {
this._age = age;
}
get age() {
console.log('获取 age');
return this._age;
}
set age(value) {
console.log('设置 age');
if (Number.isInteger(value) && value >= 0 && value
<h3>用 Proxy 全局拦截所有属性访问</h3>
<p>当需要统一拦截整个对象的任意属性(包括动态新增、遍历、in 检测等),<code>Proxy</code> 是更强大灵活的选择:</p>
-
get(target, prop, receiver)拦截读取,可返回计算值、做日志、触发响应式更新等 -
set(target, prop, value, receiver)拦截赋值,可校验、转换、通知变更 - 相比 defineProperty,Proxy 不修改原对象,支持数组索引、Symbol 属性、原型链访问等
示例:
const original = { count: 0 };
const handler = {
get(target, prop) {
console.log(`读取 ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop, value) {
console.log(`设置 ${prop} = ${value}`);
if (prop === 'count' && typeof value !== 'number') {
throw new TypeError('count 必须是数字');
}
return Reflect.set(target, prop, value);
}
};
const proxied = new Proxy(original, handler);
console.log(proxied.count); // 读取 count → 0
proxied.count = 5; // 设置 count = 5
注意事项与常见陷阱
实际使用中需注意几个关键细节:
- 避免在 getter 中直接读取自身属性(如
return this.xxx),否则可能引发无限递归 - setter 中若要真正赋值,推荐用
Reflect.set或操作私有字段(如_xxx),而非this.xxx = value(可能再次触发 setter) - defineProperty 默认不可枚举、不可配置,如需 for...in 遍历或 delete,需显式设
enumerable: true和configurable: true - class 中的 getter/setter 无法在静态方法中通过
this访问(除非是 static get/set)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










