【问题标题】:Detecting changes in a JavaScript class property?检测 JavaScript 类属性的变化?
【发布时间】:2020-11-20 05:36:33
【问题描述】:

假设你有这个类:

class Foo {
  constructor() {
    this.count = 0
  }
  increaseCountEventually() {
    setTimeout(() => {
      this.count += 1
    }, Math.floor(Math.random() * 1000))
  }
}

然后你创建这个类的一个实例:

const foo = new Foo()

然后调用increaseCountEventually 方法,该方法将在某个随机时间点增加其属性this.count 的值:

foo.increaseCountEventually()

因此,在几毫秒内计数将增加 1。有没有技巧可以监听 foo 实例的 count 属性的变化?类似于事件侦听器,其中事件将是 count 属性的更改。像这样的东西(伪代码):

// A bit like DOM events
foo.addEventListener('property count changes', () => console.log('it changed!')) 

// Or, in other terms:
foo.listenForCountChange(() => console.log('it changed!')

我可以使用setInterval 并每隔毫秒左右检查一下count 是否发生了变化,但我正在寻找一种更有效的方法。我读过有关使用“代理”的信息,但不确定它是如何工作的。

【问题讨论】:

    标签: javascript oop object dom-events prototype-programming


    【解决方案1】:

    Javascript Proxy 用于对象。如果可以将 count 转换为对象或使用属性 count 保留名为 data 的对象,那么您可以添加带有 set 陷阱的代理

    但是,在您的情况下,您可以修改 increaseCountEventually 以接受这样的函数

    increaseCountEventually(callback) {
        setTimeout((callback) => {
          this.count += 1,
          callback();
        }, Math.floor(Math.random() * 1000))
      }
    

    【讨论】:

      【解决方案2】:

      另一种监控属性更新的公平方法是在内部以另一个名称存储外部属性,例如count_count,然后使用外部属性名称设置setter/getter 对。 setter 可以在值更新时采取任何需要的操作。例如:

      class Foo {
        constructor() {
          this._count = 0; // internal property name
        }
        increaseCountEventually() {
          setTimeout(() => {
            this.count += 1
          }, Math.floor(Math.random() * 1000))
        }
        set count(value) { // external property name
          this._count = value;
          console.log( `count setter set _count to ${value}`);
        }
        get count() {
          return this._count;
        }
      }
      
      const foo = new Foo();
      console.log("foo.count = %s", foo.count);
      foo.increaseCountEventually()
      setTimeout( ()=>console.log("foo.count = %s", foo.count), 2000);

      默认情况下,_count 属性可以在类实例上枚举,并且不受写保护。如果需要,构造函数可以将_count 添加为不可枚举的属性,如下所示:

      constructor() {
        // make _count non enumerable:
      
        Object.defineProperty(this, '_count', {
           value: 0,
           enumerable: false,
           writable: true
        });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多