检测 JavaScript class 属性 中的变化?

Detecting changes in a JavaScript class property?

假设你有这个 class:

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

然后你创建一个实例 class:

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 Proxy 用于对象。如果可以将 count 转换为对象或使用 属性 count 保留名为 data 的对象,那么您可以添加一个带有 set trap

的代理

然而,在您的情况下,您可以修改 increaseCountEventually 以接受像这样的函数

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

另一种监视 属性 更新的合理方法是在内部以另一个名称存储外部 属性,例如 _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 属性 在 class 实例上是可枚举的,并且没有写保护。如果需要,构造函数可以将 _count 添加为不可枚举的 属性,如下所示:

constructor() {
  // make _count non enumerable:

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