使用 static 存取 JS 物件

JavaScript 模組通常會匯出任意的靜態物件,供其提供的介面使用。這些物件可以透過在 extern 區塊中宣告一個具名的 static 並使用 #[wasm_bindgen(thread_local_v2)] 屬性,從 Rust 中存取。wasm-bindgen 會為這些物件綁定一個 JsThreadLocal,它可以被克隆到一個 JsValue 中。

這些值會快取在執行緒本地,並且僅限於綁定靜態值或物件。對於可能變更回傳值或拋出錯誤的 getter,請參閱如何匯入 getter

例如,給定以下 JavaScript:

let COLORS = {
    red: 'rgb(255, 0, 0)',
    green: 'rgb(0, 255, 0)',
    blue: 'rgb(0, 0, 255)',
};

static 可以幫助從 Rust 存取這個物件:

#![allow(unused)]
fn main() {
#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(thread_local_v2)]
    static COLORS: JsValue;
}

fn get_colors() -> JsValue {
    COLORS.with(JsValue::clone)
}
}

由於 COLORS 實際上是一個 JavaScript 命名空間,我們可以使用相同的機制直接引用從 JavaScript 模組匯出的命名空間,甚至是匯出的類別:

let namespace = {
    // Members of namespace...
};

class SomeType {
    // Definition of SomeType...
};

export { SomeType, namespace };

這個模組的綁定:

#![allow(unused)]
fn main() {
#[wasm_bindgen(module = "/js/some-rollup.js")]
extern "C" {
    // Likewise with the namespace--this refers to the object directly.
    #[wasm_bindgen(thread_local_v2, js_name = namespace)]
    static NAMESPACE: JsValue;

    // Refer to SomeType's class
    #[wasm_bindgen(thread_local_v2, js_name = SomeType)]
    static SOME_TYPE: JsValue;

    // Other bindings for SomeType
    type SomeType;
    #[wasm_bindgen(constructor)]
    fn new() -> SomeType;
}
}

可選的靜態變數

如果您預期您嘗試存取的 JavaScript 值不一定總是可用,您可以使用 Option<T> 來處理:

#![allow(unused)]
fn main() {
extern "C" {
    type Crypto;
    #[wasm_bindgen(thread_local_v2, js_name = crypto)]
    static CRYPTO: Option<Crypto>;
}
}

如果 crypto 在 JavaScript 中沒有宣告或為空值 (nullundefined),它在 Rust 中只會回傳 None。這也會考慮命名空間:只有在所有部分都被宣告且不為空值時,它才會回傳 Some(T)

靜態字串

可以匯入字串,以避免在只需要 JsString 時經過 TextDecoder/Encoder。這在處理無法使用 TextDecoder/Encoder 的環境時非常有用,例如在音訊工作元件中。

#![allow(unused)]
fn main() {
#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(thread_local_v2, static_string)]
    static STRING: JsString = "a string literal";
}
}