You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为JavaScript对象定义全局Getter/Setter以监听所有属性读写?

当然可以!在JavaScript里,要实现监听对象所有属性(包括后续新增的属性)的读写操作,最现代也最靠谱的方案是用Proxy API——它专门用来创建对象的代理,能拦截并自定义对象的各种基本操作。下面一步步给你实现需求:

简单版:监听所有读写操作

我们可以通过Proxy的get和set陷阱,拦截所有属性的读取和设置行为,触发统一的日志输出:

const obj = { foo: 'bar', boop: "beep" };

// 创建代理对象,替代原对象使用
const proxyObj = new Proxy(obj, {
  // 拦截属性读取操作
  get(target, prop) {
    console.log("a set/get action was just triggered on obj!");
    return target[prop]; // 返回原属性值
  },
  // 拦截属性设置操作
  set(target, prop, value) {
    console.log("a set/get action was just triggered on obj!");
    target[prop] = value; // 给原对象设置新值
    return true; // 必须返回true表示设置成功,否则会抛出错误
  }
});

// 测试效果
proxyObj.foo = "not bar anymore!"; // 输出:a set/get action was just triggered on obj!
proxyObj.rand = "a randomly added prop here"; // 输出:a set/get action was just triggered on obj!
proxyObj.boop; // 读取属性也会触发日志输出

注意:之后要操作原对象的话,记得使用proxyObj而不是原obj,否则不会触发拦截。

进阶版:输出属性名和对应值

只需要修改Proxy陷阱函数的日志内容,把当前操作的属性名和值打印出来即可:

const obj = { foo: 'bar', boop: "beep" };

const proxyObj = new Proxy(obj, {
  get(target, prop) {
    console.log(`a set/get action was just triggered on obj with prop: "${prop}", value: "${target[prop]}".`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`a set/get action was just triggered on obj with prop: "${prop}", value: "${value}".`);
    target[prop] = value;
    return true;
  }
});

// 测试效果
proxyObj.boop = "burp"; // 输出:a set/get action was just triggered on obj with prop: "boop", value: "burp".
proxyObj.newRand = "a new randomly added prop here"; // 输出对应属性名和值的日志
proxyObj.foo; // 读取时会输出当前属性的名称和值

其他可选方案(不推荐用于现代项目)

如果需要兼容非常老旧的环境(不支持ES6),可以考虑以下方案,但它们都有明显局限性:

  • __defineGetter__/__defineSetter__(已废弃):只能给已有属性添加读写拦截,没法处理后续新增的属性,而且属于非标准API,现在已经被Proxy取代:
    const obj = { foo: 'bar', boop: "beep" };
    
    // 给已有属性逐个添加拦截
    Object.keys(obj).forEach(prop => {
      let internalValue = obj[prop];
      delete obj[prop];
    
      obj.__defineSetter__(prop, (newVal) => {
        console.log(`a set/get action was just triggered on obj with prop: "${prop}", value: "${newVal}".`);
        internalValue = newVal;
      });
    
      obj.__defineGetter__(prop, () => {
        console.log(`a set/get action was just triggered on obj with prop: "${prop}", value: "${internalValue}".`);
        return internalValue;
      });
    });
    
    // 新增属性不会被监听
    obj.newProp = "test"; // 不会触发任何日志
    
  • Object.observe(完全废弃):这个API曾经用来监听对象变化,但ES2016已经彻底移除,现在没有浏览器支持它,完全不建议使用。

总结

如果你的项目环境支持ES6+(现在绝大多数浏览器和Node.js版本都支持),优先使用Proxy——它能完美处理所有属性(包括新增属性)的读写拦截,API设计也更优雅灵活。老方案仅适合极端老旧环境的兼容场景,不推荐在现代项目中使用。

内容的提问来源于stack exchange,提问作者aviya.developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:15:18