Reputation: 7649
How do I trap actions where a property is set from inside a constructor?
class Foo {
constructor() {
setTimeout(() => this.value = 'value', 1000)
}
}
const foo = new Foo()
const $foo = new Proxy(foo, {
set(target, key, value) {
if (target[key] === value) return
target[key] = value
console.log('Set', key, value)
return true
}
})
While here I am directly referencing Foo
, in reality the Proxy
implementation is inside a function with no knowledge of Foo
, conversely Foo
has no knowledge that it will be proxied. The solution should allow the usage of any class to be proxied, eg
const foo = new (ProxyWrapper(Foo))()
const bar = new (ProxyWrapper(Bar))()
const foobar = new (ProxyWrapper(Foobar))()
Upvotes: 0
Views: 79
Reputation: 138267
You could create a Proxy on the prototype of the class:
class Foo {
constructor() {
setTimeout(() => this.value = 'value', 1000)
}
}
const Trap = Object.assign(function() {}, {
prototype: new Proxy({}, {
set(target, key, value) {
target[key] = value;
console.log("Set", target, key, value);
return true;
},
}),
});
const $Foo = function () {
return Reflect.construct(Foo, [], Trap);
}
const foo = new $Foo();
setTimeout(() => console.log(foo), 1100)
As a function injecting the trap that could be written as:
function TrapMe(Super) {
function Trapped() {
return Reflect.construct(Super, [], Trapped);
}
Trapped.prototype = new Proxy(Object.create(Super.prototype), {
set(target, key, value) {
target[key] = value;
console.log("Set", target, key, value);
return true;
}
});
return Trapped;
}
const Foo = TrapMe(class Foo {
constructor() {
console.log("constructed");
setTimeout(() => this.value = "value", 1000);
}
});
new Foo();
Upvotes: 2