That's probably not what you should do. (Anything with "reflection" in it is likely not what you should do most of the time, in fact.)
If you are writing a Rust function, chances are you know the exact layout (names and types of fields) of the object you are receiving. So you could just declare a statically typed struct and use JsValue::into_serde() to convert the dynamic JavaScript value to a value your static type.
In Rust - probably nothing, except if it has to work with somewhat obscure JS API. It was added to js_sys mostly for API completeness, not for some specific use.
/// Representation of an object owned by JS.
///
/// A `JsValue` doesn't actually live in Rust right now but actually in a table
/// owned by the `wasm-bindgen` generated JS glue code. Eventually the ownership
/// will transfer into wasm directly and this will likely become more efficient,
/// but for now it may be slightly slow.
pub struct JsValue {
idx: u32,
_marker: marker::PhantomData<*mut u8>, // not at all threadsafe
}
I think part of the 'clunkiness' in dealing with the JsValue API is that a JsValue is really a u32, pointing at a table, which stores the actual JS objects.
I see. It's unfortunate haha. I'm quite far off from dealing with all the clunkiness rust/wasm/js has. I continue to run into it and it's near impossible for me to read the documentation and understand - implement it.
Hopefully in 2/3 years or so this will be a bit more intuitive.
I'll continue to read more into your suggestions/examples though, thanks!
Yeah, unfortunately there is no way for WebAssembly to reference JavaScript objects at the moment[1]. To work around this, libraries like wasm-bindgen and emscripten use a bit of extra indirection and glue code to make it look like you are passing around JavaScript objects when you are actually just passing around some sort of token.
There are a couple ways you could implement this. The Reflect-based version you are asking about looks like this:
use js_sys::Reflect;
use wasm_bindgen::JsString;
pub fn initialize_x(obj: JsValue) {
let key = JsString::from_str("width");
let width = Reflect::get(&obj, &key).unwrap();
console::log_1(&width);
}