【问题标题】:Overriding ES6 class behaviour with traps用陷阱覆盖 ES6 类行为
【发布时间】:2018-08-08 03:44:16
【问题描述】:

我最近了解了 javascript 中的 Proxy 对象,以及如何使用 Proxy 对象连接到 Object.defineProperty 以实现自定义行为(如果我太含糊,请参阅 this answer)。

我也想做同样的事情,但要针对整个类,这样我就可以实现类似于 C# 的INotifyPropertyChanged 接口的东西。本质上,该类将是一个EventEmitter,它会在属性更改时发出数据。

class SyncedObject extends EventEmitter {
    constructor() {
        this.ValueA = 1;
        this.ValueB = 2;
    }

    // Emit this when a property is changed
    emitPropertyChanged( eventArgs ) {
        // eventArgs.propertyName
        // eventArgs.oldValue
        // eventArgs.newValue

        this.emit( 'propertyChanged', eventArgs );
    }
}

这是我可以在 ES6 课程中做的事情吗?我知道Proxy 有一个get()set() 陷阱可以实现这种事情,但我不确定如何编写一个自动包装在Proxy 中的类。

【问题讨论】:

  • 它是 ES6。而且没有 ES7。是的,这可以通过 Proxy 来实现。根据您的情况,出于性能原因,使用 get/set 访问器可能会更好;代理要慢得多。
  • 修复了标题。 Getter 和 setter 可以工作,但我的特定用例将受益于能够动态挂钩到任意对象的属性。我不希望属性每分钟更新一次以上,所以在这种情况下,性能不是一个大问题
  • 全班,在什么意义上?
  • 是的,我想以某种方式将Proxy 陷阱应用于整个SyncedObject 类。我也一直在思考将SyncedObject 本身变成Proxy 的想法,然后用它来“包装”其他对象,但我能想到的唯一方法是拥有一个保存相关对象的属性,所以我必须做类似SyncedObject.Data.ValueA 的事情,如果可能的话我想避免这样做

标签: node.js ecmascript-6


【解决方案1】:

经过一番修补,我已经或多或少地实现了我希望的目标

const EventEmitter = require( 'events' );

class SyncedObject extends EventEmitter { 
  constructor( obj ) {
    super();
    this._object = obj;

    return new Proxy( this, {
      set: ( object, key, value, proxy ) => {
        if( this._object[key] === value )
          return false;

        this._object[key] = value;
        if( key[0] === '_') {
            var eventArgs = {
              propertyName: key,
              oldValue: object[key],
              newValue: value
            };
            this.emit( 'propertyChanged', eventArgs );
        }

        return true;
      },
      get: ( object, key ) => {
        return this._object[key] || object[key];
      }
    });
  }

  silentUpdate( data ) {
    for(var i = 0, keys = Object.keys(data); i < keys.length; i++)
      this._object[keys[i]] = data[keys[i]];
  }

}

不是最防弹的解决方案(EventEmitter 属性引发事件),但对于我需要的,它可能会做。如果有人有改进建议,请发表。这个问题我暂时搁置。

【讨论】:

    猜你喜欢
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多