ftk / quickjspp

QuickJS C++ wrapper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

'this' is undefined when calling static JS class method from C++

AaronWright3 opened this issue · comments

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.

commented

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.