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

为何QJSEngine在多次evaluate调用间会丢失类定义?

QJSEngine多次evaluate调用中类定义丢失的原因

问题现象

使用QJSEngine::evaluate执行以下JS代码时:

class TemplateRenderer{}

function TemplateRenderer2(){}

var obj1 = new TemplateRenderer2();// 正常执行
var obj2 = new TemplateRenderer(); // 正常执行

第一次调用evaluate一切正常,但第二次调用evaluate执行以下代码时:

var obj3 = new TemplateRenderer2();// 正常执行
var obj4 = new TemplateRenderer(); // 抛出错误:ReferenceError: TemplateRenderer is not defined

类TemplateRenderer的定义在两次evaluate调用间丢失了,但函数TemplateRenderer2却能正常访问。

复现用C++代码

#include <QCoreApplication>
#include <QJSEngine>


auto main(int argn, char* argv[] ) -> int
{
    QCoreApplication app(argn, argv);
    QJSEngine engine;
    engine.installExtensions(QJSEngine::ConsoleExtension);

    QString initialCode = R"(
    class TemplateRenderer{}

    function TemplateRenderer2(){}

    var obj1 = new TemplateRenderer2();// OK
    var obj2 = new TemplateRenderer(); // OK

    )";

    auto ret = engine.evaluate(initialCode);
    qDebug() << ret.toString();

    QString secondCode = R"(
    var obj3 = new TemplateRenderer2();// OK
    var obj4 = new TemplateRenderer(); // FAILS
    )";

    auto ret2 = engine.evaluate(secondCode);
    qDebug() << ret2.toString();

}

使用Qt版本:6.8.1

原因分析

这是由JavaScript中类声明(class)和函数声明(function)的作用域绑定规则差异导致的:

  • 函数声明(function TemplateRenderer2(){})在全局作用域执行时,会自动挂载到全局对象上,因此后续的evaluate调用可以直接访问这个全局属性。
  • 类声明(class TemplateRenderer{})即使在全局作用域中,也不会自动挂载到全局对象。它的作用域仅局限于当前evaluate执行的代码块的词法作用域内,当这次evaluate执行完毕后,类定义不会被保留到全局对象中,所以第二次evaluate调用时无法找到该类。

解决方法

如果需要让类定义在多次evaluate调用间保持可用,有两种常见方式:

  1. 将类显式挂载到全局对象:
    修改第一次执行的JS代码,把类赋值给全局对象的属性:

    // 显式挂载到全局对象
    globalThis.TemplateRenderer = class TemplateRenderer{};
    
    function TemplateRenderer2(){}
    

    QJSEngine中的全局对象可通过globalThis访问,后续evaluate调用就能直接访问到类定义。

  2. 使用表达式定义类并赋值给变量:
    用类表达式的方式定义类,并赋值给全局变量:

    var TemplateRenderer = class {};
    
    function TemplateRenderer2(){}
    

    这种方式会把类赋值给全局变量,和函数声明的效果一致,后续evaluate调用可直接访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:00