Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
AaronWright3 opened this issue Feb 5, 2022 · 2 comments
Closed

Comments

@AaronWright3
Copy link

AaronWright3 commented Feb 5, 2022

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.

@ftk
Copy link
Owner

ftk commented Feb 8, 2022

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

@AaronWright3
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants