Closed dmitshur closed 3 years ago
Workaround: you can call JS String
methods via the String.prototype
itself, i.e. in JS:
String.prototype.toLowerCase.call("FOO")
In Go:
js.Global().Get("String").Get("prototype").Get("toLowerCase").Call("call", js.ValueOf("FOO"))
I have used this in gopherjs/vecty#251 in order to workaround this problem.
If not, should it be possible?
I think it should. The current API relies on Reflect.get
which only works on objects, and therefore fails on normal strings. With a little bit of code, and now with the argument spread syntax available, I was able to make it work.
fmt.Println(body.Get("nodeName").Call("toLowerCase"))
fmt.Println(body.Get("nodeName").Call("charAt", 3))
Not pasting the code here. But I can send a CL if Richard is okay with it.
This is because of JavaScript's autoboxing. string
and String
are two distinct types. The first is the primitive type, the second one is the boxed object type and only the second has methods. Autoboxing makes it so the expression
"foo".toUpperCase()
gets interpreted as
new String("foo").toUpperCase()
I do not yet see why syscall/js should emulate autoboxing. Is there any proper use case? In my opinion, for the examples above the proper solution is to use the .String()
method to get the Go string and then use Go's functions for manipulating the string.
Thanks for the explanation.
I do not yet see why syscall/js should emulate autoboxing.
I agree, I don't think that would be a good change.
In my opinion, for the examples above the proper solution is to use the .String() method to get the Go string and then use Go's functions for manipulating the string.
It should also be possible to use JavaScript's toLowerCase
explicitly, if one wants to (e.g., to avoid having to import strings
package, or for other JavaScript functions where there isn't equivalent Go functionality).
It sounds like it is possible with one of these two ways:
var str string = "FOO"
js.Global().Get("String").New(str).Call("toLowerCase")
// or
js.Global().Get("String").Get("prototype").Get("toLowerCase").Call("call", str)
So nothing needs to be done. I'll close this if there aren't objections.
It looks like there are no objections. ping @dmitshur.
With GopherJS, it was possible to call the
String.prototype.toLowerCase
method on a JavaScriptString
:https://gopherjs.github.io/playground/#/ekZpm7tuW4
It's possible I'm overlooking something trivial, but this doesn't seem possible with
syscall/js
API of WebAssembly. Consider the same program modified to usesyscall/js
:Its output with Go 1.13.4 is:
Depending on whether a JavaScript
String
type is considered a "JavaScript object" or not, this may be consistent withjs.Value.Get
documentation, which says:I'm wondering if it's possible to use
toLowerCase
withsyscall/js
API? If not, should it be possible?/cc @neelance