【问题标题】:ECMAscript 6: watch changes to class propertiesECMAscript 6:观察类属性的变化
【发布时间】:2017-09-13 15:32:53
【问题描述】:

假设我有一个定义如下的类:

class MyClass {

    constructor (a) {
        this.a = a;     
    }

    _onPropertyChanged() {
        // do something
    }
}

每当 MyClass 实例的属性“a”发生变化时,我都想在该实例上触发 _onPropertyChanged 方法。 使用 ECMAscript 6 实现这一目标的最佳(最高性能)方法是什么?

【问题讨论】:

  • 你为什么要这样做?您需要查看所有属性,还是只查看固定属性?
  • “最高性能”---“性能”不是系统的绝对属性。不过,可以比较给定环境中的多个实现。
  • a 的分配可以使用访问器方法轻松跟踪,如答案所示。如果您想跟踪值是否不同等,问题将自动落入“太宽泛”的类别。性能变更检测是所有现代 JS 框架都必须解决的复杂任务。不要指望他们的经历可以用一个答案来解释。
  • 查看Proxy

标签: javascript class ecmascript-6 watch


【解决方案1】:

最好的方法是重新定义归档/属性,但在这种情况下,你会遇到一些坑,比如“找到这个道具的所有者”。您可以使用this 解决方案进行完全安全的属性重新定义。

主要思想是如果存在则重新定义属性:

 Object.defineProperty(target, name, {
     get() { return get(ownPropertyDescriptor.get.call(target)); },
     set(val) {
         let _val = set.call(this, val);
         if (_val != undefined)
            ownPropertyDescriptor.set.call(target, _val);
         },
     configurable: true
 });

或者根据symbol类型创建新属性:

var indexer = Symbol(name);
target[indexer] = target[name];
Object.defineProperty(target, name, {
  get() {
         var val = target[indexer];
         var _val = get(val);
           return _val;
     },
  set(val) {
         let _val = set.call(this, val);
         arget[indexer] = set(_val);
     },
  configurable: true
});

Full method is part of complex solution for property-redefining.

【讨论】:

    【解决方案2】:

    最简单的事情是为属性定义一个setter和一个getter,就像previous comment说的那样。但是,如果您已经定义了 setter,它将无法工作。

    另一种方式是非标准的 Object.prototype.watch,它只能在 Gecko 中本地工作。如果你想把它的支持带到大多数其他浏览器,你可以使用一个小而强大的Andrea Giammarchi's library

    【讨论】:

      【解决方案3】:

      没有“最好”的方法,实际的方法总是取决于最终目标。

      以其简单(且性能足够)的形式是:

      class MyClass {
      
          constructor (a) {
            this.a = a;     
          }
      
          get a() {
            return this._a;
          }
      
          set a(val) {
            this._a = val;
            this._onPropertyChanged('a', val);
          }
      
          _onPropertyChanged(propName, val) {
              // do something
          }
      }
      

      【讨论】:

      • 构造函数中的错字:缺少下划线。
      • @cartant 这不是错字。构造函数改变a属性,调用onPropertyChanged钩子。
      【解决方案4】:

      这是一个简单的示例,说明您可以针对这种情况和单个属性执行哪些操作。

      class MyClass {
      
      constructor (a) {
          this._a = a;
      }
      
      set a(value) {
          let hasChanged = (this._a !== value);
          this._a = value;
          //Assumes value is primitive. Customize for objects
          if(hasChanged) this._onPropertyChanged();
      
      }
      
      _onPropertyChanged() {
          // do something
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-24
        • 1970-01-01
        • 2017-09-07
        • 2018-04-10
        相关资源
        最近更新 更多