QJSEngine 全局字符串比较

Posted

技术标签:

【中文标题】QJSEngine 全局字符串比较【英文标题】:QJSEngine global string compare 【发布时间】:2018-12-28 10:02:18 【问题描述】:

我使用的是 Qt 5.11.2,在我的应用程序中我使用的是 QJSEngine,在我的示例中我有一个脚本:

    function connect() 
        console.info("-----------");
        if ( strFirstScan.localeCompare("true") == 0 ) 
            console.info("First scan");
            strFirstScan = "false";
            a = eval(a);
            b = eval(b);
            c = eval(c);
        
        console.info("strFirstScan: " + strFirstScan + ", typeof: " + typeof strFirstScan); 
        console.info("a: " + a + ", typeof: " + typeof a);
        a++;
        console.info("b: " + b + ", typeof: " + typeof b);
        console.info("c: " + c + ", typeof: " + typeof c);
        console.info("-----------");
    

我已将此脚本连接到应用程序中的一个按钮,当我单击该按钮时,脚本会调用 connect() 函数。我已经注册了一些用于脚本的全局变量:

    strFirstScan = "true"
    a = 123
    b = "Hello"
    c = "a":1,"b":"A","c":"aa":1

单击按钮时脚本应用程序的输出是:

    2018-12-28 09:55:10.079663+0000 XMLMPAM[2470:247691] [js] -----------
    2018-12-28 09:55:10.079718+0000 XMLMPAM[2470:247691] [js] strFirstScan: "true", typeof: string
    2018-12-28 09:55:10.079742+0000 XMLMPAM[2470:247691] [js] a: 123, typeof: string
    2018-12-28 09:55:10.079775+0000 XMLMPAM[2470:247691] [js] b: 'hello', typeof: string
    2018-12-28 09:55:10.079804+0000 XMLMPAM[2470:247691] [js] c: "a":1,"b":"A","c":"aa":1, typeof: string
    2018-12-28 09:55:10.079832+0000 XMLMPAM[2470:247691] [js] -----------

我从来没有看到“第一次扫描”,变量的类型仍然是字符串,因为它没有进入 eval 语句。

为什么比较不起作用?我尝试了许多替代方案:

    if ( strFirstScan == "true" ) 

    if ( strFirstScan.compare("true") == 0 ) 

这些都不是更好,为什么比较不起作用?

[编辑] 我已将脚本修改为:

    function connect() 
        console.info("-----------");
        if ( typeof strFirstScan == "string" ) 
            console.info("First scan");
            console.info("strFirstScan: " + strFirstScan + ", typeof: " + typeof strFirstScan); 
            strFirstScan = 0;
            a = eval(a);
            b = eval(b);
            c = eval(c);
        
        console.info("a: " + a + ", typeof: " + typeof a);
        a++;
        console.info("b: " + b + ", typeof: " + typeof b);
        console.info("c: " + c + ", typeof: " + typeof c);
        console.info("-----------");
    

使用这样的脚本,我在输出中得到以下内容:

    2018-12-28 10:22:31.267553+0000 XMLMPAM[2993:335615] [js] -----------
    2018-12-28 10:22:31.267595+0000 XMLMPAM[2993:335615] [js] First scan
    2018-12-28 10:22:31.267629+0000 XMLMPAM[2993:335615] [js] strFirstScan: "true", typeof: string
    2018-12-28 10:22:31.267804+0000 XMLMPAM[2993:335615] [js] a: 123, typeof: number
    2018-12-28 10:22:31.267832+0000 XMLMPAM[2993:335615] [js] b: hello, typeof: string
    2018-12-28 10:22:31.267877+0000 XMLMPAM[2993:335615] [js] c: [object Object], typeof: object
    2018-12-28 10:22:31.267897+0000 XMLMPAM[2993:335615] [js] -----------

但是,如果我向 if 条件添加任何比较,将字符串与“true”进行比较,如果没有传递到第一个扫描条件。

[Edit2] 我将创建全局变量“strFirstScan”的代码修改为:

    pobjScriptEng->globalObject().setProperty("strFirstScan", QJSValue("true"));

这现在解决了问题和我的脚本:

    if ( strFirstScan == "true" ) 

工作。

【问题讨论】:

【参考方案1】:

从你的程序输出来看,strFirstScan 不是true,而是"true"

您可以通过在日志输出中的值周围添加某种引号来验证这一点。即:console.info("strFirstScan: '" + strFirstScan + "', typeof: " + typeof strFirstScan);

这是演示您的问题的 sn-p:

var yourCase = '"true"';
console.info('value: ' + yourCase + ', type: ' + typeof yourCase + ', len: ' + yourCase.length);
console.info(yourCase === "true");

var youWant = 'true';
console.info('value: ' + youWant + ', type: ' + typeof youWant + ', len: ' + youWant.length);
console.info(youWant === "true");

但是,从您提供的内容中无法判断为什么您的代码会表现得如此准确。

【讨论】:

有什么区别?我将 strFirstScan 的值与“true”进行比较。 在输出中,类型显示为“string”,值为“true”。 @SPlatten 你将它与true 进行比较,即字符串true(没有双引号),当它看起来像时(不能确定,因为你没有提供MVCE ) 你有"true",即双引号是字符串的一部分。查看b 的输出(相同,只是用单引号而不是双引号)。 我将它与字符串文字进行比较,引号是真实的,使其成为字符串。 @SPlatten 您的日志表明strFirstScan 不是"true" 而是'"true"',即包含双引号的字符串。我不知道为什么,因为根据您提供的内容,我无法重现它,甚至无法准确猜测会发生什么(evals 是什么?可能是错误的)。查看第二个日志中b 的行。 b: hello, typeof: string,请注意 console.info 不会在 hello 周围打印额外的引号,即使 b === "hello",但它会为 strFirstScan 显示它是 strFirstScan === "\"true\"" 出于某种原因。【参考方案2】:

我将创建全局变量“strFirstScan”的代码修改为:

pobjScriptEng->globalObject().setProperty("strFirstScan", QJSValue("true"));

这现在解决了问题和我的脚本:

if ( strFirstScan == "true" ) 

这解决了问题,现在可以正常工作了。

【讨论】:

以上是关于QJSEngine 全局字符串比较的主要内容,如果未能解决你的问题,请参考以下文章

访问 Class 对象以与全局变量进行比较

如何使用 QJSEngine 构建 API?

在脚本调用的 C++ 函数中调用 QJSEngine::newQObject() 是不是有效?

R中字符的对象大小 - R全局字符串池如何工作?

js判断字符串是不是相等

当我尝试与另一个 NSString 进行比较时,NSString 仅显示内存地址