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

Duktape JS多上下文持独立全局时如何实现跨脚本共享单例对象

实现方案(基于Duktape嵌入环境)

你当前的需求本质是在多个隔离的JS全局上下文之间共享一个单例对象,Duktape原生提供了堆级别的存储能力,可以非常轻量的实现该需求,以下是两种生产环境常用的实现方式:

方案1:独立全局环境预注入共享对象(最推荐,无副作用)

这是最轻量、无原型污染的实现方式,只需要在C层做两处修改即可:

步骤1:初始化阶段创建全局共享的ueber单例

在Duktape上下文初始化完成后、加载任何业务脚本之前,执行一次以下代码,把ueber对象存入堆存储(heap stash,Duktape堆全局持有,不会被GC,所有上下文都可访问):

// 初始化阶段仅执行1次
duk_push_object(js_context_duk); // 创建空的ueber共享对象
// 如果需要给ueber预置内置方法/属性,可以在这里补充定义
// duk_push_c_function(js_context_duk, your_c_func, 0);
// duk_put_prop_string(js_context_duk, -2, "builtinMethod");
duk_put_heap_stash(js_context_duk, "shared_ueber"); // 存入堆存储永久持有

步骤2:每个新脚本初始化时注入ueber到其独立全局作用域

你当前每个脚本有独立全局作用域,应该是每个脚本加载前都会创建新的全局对象,在创建完新的全局对象之后、执行业务脚本之前,执行以下代码注入共享对象:

// 每个独立脚本初始化时执行
duk_get_heap_stash(js_context_duk, "shared_ueber");
duk_put_global_string(js_context_duk, "ueber");

完成以上两步后,所有脚本里访问的ueber都是同一个对象的引用,修改/读取属性都是全局共享的,完全符合你给出的使用示例要求。

方案2:原型链挂载共享对象

如果你不想每次初始化脚本都手动注入,可以把ueber挂载到所有对象的公共原型链上,缺点是会轻微污染原型,不需要额外的注入操作:

// 初始化阶段执行一次
duk_push_object(js_context_duk); // 创建ueber对象
duk_get_global_string(js_context_duk, "Object");
duk_get_prop_string(js_context_duk, -1, "prototype");
duk_put_prop_string(js_context_duk, -2, "ueber");
duk_pop_2(js_context_duk);

效果验证

按照上述方案实现后,你的示例代码可以正常运行:

  • 脚本2执行ueber.a=1后,脚本1内读取ueber.a即可得到正确的值,所有脚本对ueber的属性修改全局生效
  • 各脚本的其他全局变量仍然是隔离的,不会互相污染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:15:01