【问题标题】:Creating decorators with access to closures创建可访问闭包的装饰器
【发布时间】:2015-11-04 17:20:31
【问题描述】:

我有很多小对象,它们都需要完成非常相似的任务,我想使用装饰器来修改这些对象,因为这对我来说更容易。问题是,我还需要在访问这些对象上的某些数据时立即触发内容,同时防止外部访问实际数据。因此,我使用闭包来存储私有数据并为外部访问提供神奇的变异器。最后,我也无缘无故地使用了构造函数。

这是一个非常简化的对象版本和让我头疼的部分:

var Foo = function () {
  var hiddenState;
  return {
    set state (s) {
      // Do something that justifies using magical accessors
      state = s;
    },
    get state () {
      // Do something that justifies using magical accessors
      return state;
    }
  }
};

var o = new Foo();
o.state = 10;

好的,现在有些对象在使用它们的 mutator 时应该表现得与其他对象不同。所以,我想,我会覆盖突变器,就是这样:

// Let's suppose I have some reason to modify the magical accessors for some objects but not for others
Object.defineProperty(o, 'state', {
  get: function () {return hiddenState /*...*/},
  set: function (s) {state = s /*...*/}
});

o.state; // Ouch!

这不起作用。我收到一个引用错误,因为我试图访问 hiddenState,但它没有在新的 getter/setter 对的范围内定义。

我怀疑 JS 会在我传入新的mutators 后立即转储只能从旧的mutators 访问的闭包。有什么办法可以解决这个问题吗?

【问题讨论】:

    标签: javascript properties closures mutators


    【解决方案1】:

    您可以使用Object.getOwnPropertyDescriptor 访问有权访问hiddenState 的闭包。另外,如果你不需要修改getter,就不要覆盖它,它会一直存在。

    var oldSetter = Object.getOwnPropertyDescriptor(o, 'state').set;
    Object.defineProperty(o, 'state', {
      set: function (s) {
        /* do something to s */
        oldSetter(s);
      }
    });
    

    【讨论】:

    • 哇!这正是我想要的!我已经在考虑使用自定义函数来保留旧的 setter,但这要好得多。
    猜你喜欢
    • 2011-06-25
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2017-02-04
    • 2020-06-20
    • 1970-01-01
    • 2010-11-10
    相关资源
    最近更新 更多