I am looking for a way to use something similar to Function.apply for classes so that the this property of an executed constructor is an external object.
With a function I can simply use apply
function Bar() {
this.value = 'value'
}
const proxy = {}
Bar.apply(proxy, [])
console.log(proxy) // { value: 'value' }
However this does not, of course, work with classes
class Foo {
constructor() {
this.value = 'value'
}
}
const proxy = {}
Foo.apply(proxy, [])
console.log(proxy)
Resulting in
Foo.apply(proxy, [])
^
TypeError: Class constructor Foo cannot be invoked without 'new'
Is it possible to bind the this context of a class constructor to another object?
I don't have any legacy clients so I am able to use Reflect.construct (though I am not sure if it can solve the problem)
EDIT:
Alternatively, I can work with replacing this after construction. Is that possible?
const foo = new Foo()
foo.bind(proxy)
If you have a look at [[Construct]] of function objects (which is the internal method which will be executed when you use new or Reflect.construct), then you'll find this step in the specification:
Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%").
As there is no way to change this behavior, you cannot change what thisArgument is, it is always a regular object and cannot be a proxy. However, if you use Reflect.construct, you can influence the newTarget, and pass something else in than the regular constructor:
class Constructed {} // this is the function object that will be [[Construct]]ed
class Trapped {} // the "thisArgument" will inherit Trapped.prototype
Reflect.construct(Constructed, [], Trapped);
By injecting a proxy into Trapped.prototype you can have some reflection onto this inside a class constructor. An example can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With