indexing_getter, indexing_setter, and indexing_deleter

These three attributes indicate that a method is an dynamically intercepted getter, setter, or deleter on the receiver object itself, rather than a direct access of the receiver's properties. It is equivalent calling the Proxy handler for the obj[prop] operation with some dynamic prop variable in JavaScript, rather than a normal static property access like obj.prop on a normal JavaScript Object.

This is useful for binding to Proxys and some builtin DOM types that dynamically intercept property accesses.

  • indexing_getter corresponds to obj[prop] operation in JavaScript. The function annotated must have a this receiver parameter, a single parameter that is used for indexing into the receiver (prop), and a return type.

  • indexing_setter corresponds to the obj[prop] = val operation in JavaScript. The function annotated must have a this receiver parameter, a parameter for indexing into the receiver (prop), and a value parameter (val).

  • indexing_deleter corresponds to delete obj[prop] operation in JavaScript. The function annotated must have a this receiver and a single parameter for indexing into the receiver (prop).

These must always be used in conjunction with the structural and method flags.

For example, consider this JavaScript snippet that uses Proxy:

const foo = new Proxy({}, { get(obj, prop) { return prop in obj ? obj[prop] : prop.length; }, set(obj, prop, value) { obj[prop] = value; }, deleteProperty(obj, prop) { delete obj[prop]; }, }); foo.ten; // 3 foo.ten = 10; foo.ten; // 10 delete foo.ten; foo.ten; // 3

To bind that in wasm-bindgen in Rust, we would use the indexing_* attributes on methods:

#[wasm_bindgen] extern "C" { type Foo; #[wasm_bindgen(thread_local_v2)] static FOO: Foo; #[wasm_bindgen(method, structural, indexing_getter)] fn get(this: &Foo, prop: &str) -> u32; #[wasm_bindgen(method, structural, indexing_setter)] fn set(this: &Foo, prop: &str, val: u32); #[wasm_bindgen(method, structural, indexing_deleter)] fn delete(this: &Foo, prop: &str); } FOO.with(|foo| { assert_eq!(foo.get("ten"), 3); foo.set("ten", 10); assert_eq!(foo.get("ten"), 10); foo.delete("ten"); assert_eq!(foo.get("ten"), 3); });