Reputation: 339
Assume you have this class:
class Foo {
constructor() {
this.count = 0
}
increaseCountEventually() {
setTimeout(() => {
this.count += 1
}, Math.floor(Math.random() * 1000))
}
}
Then you create an instance of this class:
const foo = new Foo()
Then you call the increaseCountEventually
method which will, at some random point in time, increment the value of its property this.count
:
foo.increaseCountEventually()
So, in a few milliseconds count will increase by 1. Is there a trick to listen for changes in the count
property of the foo
instance? Something like an event listener, where the event would be the change of the count
property. Something like this (pseudo-code):
// A bit like DOM events
foo.addEventListener('property count changes', () => console.log('it changed!'))
// Or, in other terms:
foo.listenForCountChange(() => console.log('it changed!')
I could use setInterval
and check every millisecond or so to see if count
has changed, but I'm looking for a more efficient way. I read about using a "Proxy" but not sure how that would work.
Upvotes: 2
Views: 1997
Reputation: 19301
Another fairly way to monitor property updates is to store the external property under another name internally, say _count
for count
, and then use the external property name to set up a setter/getter pair. The setter can take whatever action is needed when the value is updated. E.G.:
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);
By default the _count
property would be enumerable on class instances, and not write protected. The constructor could add _count
as a non-enumerable property if so desired, along the lines of:
constructor() {
// make _count non enumerable:
Object.defineProperty(this, '_count', {
value: 0,
enumerable: false,
writable: true
});
}
Upvotes: 1
Reputation: 774
Javascript Proxy are meant to be used on Objects. If its okay to convert count into an object or keep an object called data with property count then you could add a proxy with a set trap
In your case however, you could modify increaseCountEventually
to accept a function like so
increaseCountEventually(callback) {
setTimeout((callback) => {
this.count += 1,
callback();
}, Math.floor(Math.random() * 1000))
}
Upvotes: 1