【问题标题】:Dynamically running Object.defineProperty on new keys在新键上动态运行 Object.defineProperty
【发布时间】:2017-04-24 13:56:40
【问题描述】:

我正在使用Object.defineProperty 覆盖对象上的getter 和setter,这样我就可以监听所有的突变事件。

var a = {};
Object.defineProperty(a, key, {
  get: function(){
    ..
  },
  set: function(val){
    ..
  }
}

这很好用,但有一个警告——我需要提前知道我想听什么属性——这意味着我需要在开始时遍历所有我想看的键。

如果我想像这样在运行时随机分配一个新属性:

a.new_attr=1;

它不起作用,因为我还没有定义 new_attr 属性。

有没有办法:

  1. 第一次分配属性时动态运行Object.defineProperty();或
  2. 还有其他方法可以处理这种情况吗? (也许可以通过某种方式在不指定键的情况下监控所有属性)

【问题讨论】:

    标签: javascript web


    【解决方案1】:

    我认为您真正想要使用的是Proxy。代理允许您拦截诸如 get 和 set 之类的事件。

    var obj = {
      a: 1,
      b: 2
    };
    var proxiedObj = new Proxy(obj, {
      get: function(target, name) {
        console.log(`get: ${name}`);
        return target[name];
      },
      set: function(target, prop, value) {
        console.log(`set: ${prop}`);
        target[prop] = value;
      }
    });
    
    console.log(proxiedObj.a);
    console.log(proxiedObj.b);
    
    // Notice that it still works even on new properties
    proxiedObj.c = 3;
    console.log(proxiedObj.c);

    【讨论】:

    • 注意:这只适用于 ES2015/ES6+ 环境,不能被转译。
    • @nils 非常好。从技术上讲,它可以被转译 (sort of),但速度非常慢。
    • 哦,哇,我以前从未见过这种解决方案。很有创意,但不适合制作。
    • 感谢您的回答,不幸的是我正在寻找一个经典的 JS 解决方案。那么这是否意味着没有适用于普通 JS 的解决方案可以在所有浏览器中开箱即用?我正在努力不使用新版本的 ES,因为我想保持简单。
    • @Vlad 没有适用于 ES5 的解决方案。代理专门用于处理此类情况。 ES5 中没有类似的机制。正如您所说,如果事先知道所有密钥,但您无法连接到新密钥,则可以使其工作。
    猜你喜欢
    • 2022-06-15
    • 2017-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多