quickjspp
quickjspp copied to clipboard
'this' is undefined when calling static JS class method from C++
I'm not sure how to use a static JS class method (containing the this
keyword) in C++ in a way that allows for passing arbitrary parameters from C++.
I have a context, into which I eval the following:
class FooBar {
static foo = "bar";
static baz() {
return this.foo;
}
}
If I do the following in C++:
auto baz = context->eval("FooBar.baz").as<std::function<void()>>();
baz();
then I will get the following error:
TypeError: cannot read property 'foo' of undefined
at baz (eval: 4)
Evaluating "FooBar.baz()"
works as intended, and replacing this.foo
with FooBar.foo
in FooBar.baz works, but I can't pass parameters to the former from C++ and the latter would fail if FooBar were ever renamed, so it's not ideal.
I've also tried executing FooBar.baz by first getting FooBar as a qjs Value and using Value.evalThis
, but that gave the same results.
For my current use case that involves passing an object from another context to many static methods to be processed, I have a workaround in which I just call a helper function from C++ that puts an arbitrary variable into globalThis (or anywhere else in the context), after which I can use an eval to call hypothetical function "FooBar.qux(arbitrary_variable)"
which is a static method using this
, and that works, but it obviously isn't ideal.
Edit: I thought of a much more satisfactory way to accomplish this for my use case. I can put an object from context A containing all of its public functions into context B, and I also put the an object with all the public variables I need from context C into context B, then I can just call a function from context A on an item from context C using context B, and I get the sandboxing I need, with no issues calling static functions from context A.
Quickjspp calls all JS functions with this
=undefined
which is probably wrong, however I don't know how to determine the correct this
object to call with, since JS_Eval doesn't return it.
Another way is to use eval("FooBar.baz.bind(FooBar)")
which will bind the correct this
Ah, that makes sense. Thank you very much! As long as there's a solution, I'll be happy. It's funny, I looked into call
and apply
to approach this, but forgot completely about bind
.