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

如何在Blazor中调用JavaScript类构造函数实例化对象

报错核心原因

你的代码有两个逻辑问题:

  • Blazor JS互操作的Invoke/InvokeAsync方法第一个参数仅支持传入可访问的函数/属性路径,不识别new 类名这类JS表达式语法。传入"new THREE.Scene"时,运行时会尝试查找名为new的全局对象下的THREE.Scene属性,自然找不到对应值。
  • 你导入的是three.js的ES模块版本,这类模块不会向全局window挂载THREE对象,所有导出的类、方法都直接挂载在导入拿到的模块实例引用上,全局作用域下根本不存在THREE变量。
无自定义JS包装的实现方案

不需要单独编写JS包装函数,Blazor本身就支持直接实例化JS类,根据你使用的.NET版本选择对应写法即可:

.NET 6及以上版本(推荐)

.NET 6开始IJSObjectReference/IJSInProcessObjectReference原生提供构造函数调用能力,写法最简洁:

// 导入three.js模块,建议将three.module.js放到项目wwwroot目录本地引用,避免远程CDN跨域、CSP拦截问题
var threeModule = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "import", 
    "./three.module.js"
);

// 从模块上拿到Scene构造函数引用(.NET 7+可以用GetProperty扩展方法,低版本用Reflect.get取属性)
var sceneCtor = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.get", 
    threeModule, 
    "Scene"
);
// 直接调用构造函数实例化,等价于JS中的 new Scene()
var scene = sceneCtor.InvokeNew<IJSInProcessObjectReference>();

// 带参数的构造函数直接按顺序传参即可,比如透视相机实例化
var cameraCtor = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.get", 
    threeModule, 
    "PerspectiveCamera"
);
var camera = cameraCtor.InvokeNew<IJSInProcessObjectReference>(75, 1920d/1080d, 0.1, 1000);

.NET 5及更低版本

低版本没有原生InvokeNew方法,可以直接调用JS内置全局APIReflect.construct实现等价的new操作,完全不需要自定义JS代码:

var threeModule = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "import", 
    "./three.module.js"
);

// 取模块上的Scene构造函数
var sceneCtor = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.get", 
    threeModule, 
    "Scene"
);
// 调用JS内置的Reflect.construct执行实例化,第二个参数为构造函数参数数组
var scene = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.construct",
    sceneCtor,
    Array.Empty<object>()
);

// 带参数的构造函数写法
var cameraCtor = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.get", 
    threeModule, 
    "PerspectiveCamera"
);
var camera = await JS.InvokeAsync<IJSInProcessObjectReference>(
    "Reflect.construct",
    cameraCtor,
    new object[] {75, 1920d/1080d, 0.1, 1000}
);
注意事项
  • 所有通过JS互操作拿到的IJSObjectReference实例用完之后必须调用Dispose()释放,否则会造成内存泄漏。
  • 不建议直接引用远程CDN上的JS模块,容易触发跨域限制、CSP拦截,也可能因为版本变动导致代码失效,把依赖的JS文件下载到本地wwwroot目录引用是最稳妥的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:57:17