Передача коллбека в QJSValue::callAsConstructor()

111
21 апреля 2021, 13:20

При попытке передать объект из C++ в JavaScript, используя QJSEngine, мистическим образом пропадают все поля, значение которых хранит функции. Почему так происходит?

qjsengine-bug

QT += core qml quick quickcontrols2
TARGET = qjsengine-bug
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11 console
SOURCES += main.cpp

main.cpp

#include <QCoreApplication>
#include <QJSValueIterator>
#include <QJSEngine>
#include <QJSValue>
#include <QtGlobal>
#include <iostream>
void myMessageOutput(
    QtMsgType t,
    const QMessageLogContext &c,
    const QString &msg
) {
    Q_UNUSED(t);
    Q_UNUSED(c);
    std::cout << msg.toStdString() << "\n";
}
int main(int argc, char *argv[]) {
    qInstallMessageHandler(myMessageOutput);
    QCoreApplication app(argc, argv);
    QJSEngine engine;
    engine.installExtensions(QJSEngine::ConsoleExtension);
    QJSValue constructor = engine.evaluate(
        "(function Component(props){console.log(JSON.stringify(props))})"
    );
    QJSValue callBack = engine.evaluate("(function(text){console.log(text)})");
    callBack.call({"There is no error. Valid JavaScript code..."});
    callBack.call({"Let's create an object, add a couple of props to it"});
    QJSValue object = engine.newObject();
    object.setProperty("First", 1);
    object.setProperty("Second", callBack);
    object.setProperty("Third", "#2");
    QJSValueIterator iter(object);
    while (iter.hasNext()) {
        iter.next();
        callBack.call({
            QString("name: %1, value: %2")
                .arg(iter.name())
                .arg(iter.value().toString())
        });
    }
    callBack.call({"Correct. Three fields"});
    callBack.call({"Let's try to pass an object to the constructor parameters"});
    constructor.callAsConstructor({object});
    callBack.call({"Where did the second property go?"});
    return app.exec();
}

Answer 1

Тут дело в JSON.stringify, который не умеет функции в строки превращать, поэтому просто пропускает свойства с функциями. Пример:

var o = {
  first: 1,
  second: function() {
    return 333;
  }
};
console.log(JSON.stringify(o)) // {first:1}
READ ALSO
Почему не равны переменые?

Почему не равны переменые?

Когда выполняю возвращает:

91
Не могу понять задачу по JS

Не могу понять задачу по JS

Не могу понять почему результат получается 8, объясните пожалуйста

90
100% высота блока в React

100% высота блока в React

С помощью npm установил ReactИз "коробки" существует файл App

80