You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JS文件中使用Rust通过wasm_bindgen导出的struct结构体?

问题原因

默认wasm_bindgen导出的Rust结构体不会自动暴露内部字段,JS侧拿到的是指向Wasm线性内存的不透明引用,因此直接打印只会显示底层指针标识,无法直接访问内部的x、y值。


解决方法

方法1:为字段添加getter/setter(最常用,保留Wasm侧实例功能)

只需要在结构体字段上添加#[wasm_bindgen(getter, setter)]属性,即可让JS侧直接读写对应字段:

#[wasm_bindgen]
pub struct Point {
    // 暴露x字段的读写能力
    #[wasm_bindgen(getter, setter)]
    pub x: i32,
    // 暴露y字段的读写能力
    #[wasm_bindgen(getter, setter)]
    pub y: i32,
}

#[wasm_bindgen]
impl Point {
    #[wasm_bindgen(constructor)]
    pub fn new(x: i32, y: i32) -> Point {
        Point { x, y }
    }
}

修改后JS侧即可正常访问字段:

let p = new Point(23, 34);
console.log(p.x); // 输出 23
console.log(p.y); // 输出 34
// 如果需要完整的对象格式,可以手动构造:
const obj = { x: p.x, y: p.y, __proto__: Point.prototype };
console.log(obj); // 输出 {x:23, y:34} 且携带Point原型

方法2:Rust侧直接返回符合要求的JS对象

如果希望直接从Rust侧得到带原型的标准JS对象,可以添加to_js_obj方法手动构造:
首先在Cargo.toml中添加依赖:

[dependencies]
js-sys = "0.3"

修改Rust代码:

use js_sys::{Object, Reflect};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub struct Point {
    x: i32,
    y: i32,
}

#[wasm_bindgen]
impl Point {
    #[wasm_bindgen(constructor)]
    pub fn new(x: i32, y: i32) -> Point {
        Point { x, y }
    }

    pub fn to_js_obj(&self) -> JsValue {
        let obj = Object::new();
        // 写入x、y属性
        Reflect::set(&obj, &"x".into(), &self.x.into()).unwrap();
        Reflect::set(&obj, &"y".into(), &self.y.into()).unwrap();
        // 绑定Point原型
        let point_constructor = Reflect::get(&js_sys::global(), &"Point".into()).unwrap();
        let point_proto = Reflect::get(&point_constructor, &"prototype".into()).unwrap();
        Object::set_prototype_of(&obj, &point_proto);
        
        obj.into()
    }
}

JS侧调用:

let p = new Point(23, 34);
let jsObj = p.to_js_obj();
console.log(jsObj); // 直接输出 {x:23, y:34} 且携带Point原型

方法3:用Serde自动序列化(适合纯数据结构体)

如果你的Point是纯数据结构体,不需要在Rust侧保留实例引用,可以启用Serde自动序列化转成JS对象:
首先修改Cargo.toml添加依赖:

[dependencies]
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
serde = { version = "1.0", features = ["derive"] }

修改Rust代码:

use serde::{Serialize, Deserialize};
use wasm_bindgen::prelude::*;

#[wasm_bindgen(serde)]
#[derive(Serialize, Deserialize)]
pub struct Point {
    pub x: i32,
    pub y: i32,
}

#[wasm_bindgen]
impl Point {
    #[wasm_bindgen(constructor)]
    pub fn new(x: i32, y: i32) -> Point {
        Point { x, y }
    }
}

修改后new Point直接返回标准JS对象,自带x、y属性。


内容的提问来源于stack exchange,提问作者akshay karande

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:27:05