简体   繁体   English

ECMAscript 6:观察类属性的变化

[英]ECMAscript 6: watch changes to class properties

Let's say I have a class defined as follows: 假设我有一个如下定义的类:

class MyClass {

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

    _onPropertyChanged() {
        // do something
    }
}

Whenever the property "a" of an instance of MyClass changes, I want to trigger the _onPropertyChanged method on that instance. 每当MyClass实例的属性“a”发生更改时,我想在该实例上触发_onPropertyChanged方法。 What is the best (most performant) way to achieve this using ECMAscript 6? 使用ECMAscript 6实现这一目标的最佳(最佳性能)方法是什么?

There's no 'best' way, and the actual approach always depends on the final goal. 没有“最佳”方式,实际方法总是取决于最终目标。

In its simplistic (and performant enough) form it is: 它的简单(和高性能)形式是:

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
    }
}

This is a simple example of what you can do for this situation and for a single property. 这是您可以针对此情况和单个属性执行的操作的简单示例。

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
}
}

The easiest thing is to define a setter and a getter for the property like the previous comment said. 最简单的方法是为该属性定义一个setter和一个getter,就像之前的评论所说的那样。 However, it won't work if you already have a defined setter. 但是,如果您已经定义了setter,它将无法工作。

Another way is a non-standard Object.prototype.watch, which only works natively in Gecko. 另一种方法是非标准的Object.prototype.watch,它只能在Gecko中本地工作。 If you want to bring its support to most other browsers, you can use a small but powerful Andrea Giammarchi's library . 如果你想为大多数其他浏览器提供支持,你可以使用一个小而强大的Andrea Giammarchi的库

The best way is redefine filed/property, but in this case u have some pit falls, like 'find owner of this prop'. 最好的方法是重新定义归档/财产,但在这种情况下,你有一些陷阱,比如“找到这个道具的所有者”。 U can use this solution for totally-safe property redefining. U可以使用解决方案进行完全安全的属性重新定义。

The main idea is redefine property if exists: 主要想法是重新定义属性,如果存在:

 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
 });

Or create new property based on symbol type: 或者根据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. 完整方法是属性重新定义的复杂解决方案的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM