I have upgraded my project from Qt 5.6.2 to Qt 5.9.4 Had a couple of issues on mac when I tried to build for the first time with the new Qt version, but nothing major. I have merged these changes and switched to Windows in order to try to build my project there as well. Unfortunately with no success due to some JS issues.
It looks like QML's JS engine works differently on Mac and Windows from Qt 5.9.4 (maybe earlier versions as well, didn't try) then it did on Qt 5.6.2.
Here is a small example, which demonstrates the root cause of my issue:
QtQuick.Item {
QtQuick.Component.onCompleted: {
function underscoreFind(obj, predicate, context) {
var findIndex = function(obj, predicate, context) {
for (var i = 0; i < obj.length; i++) {
if (predicate(obj[i])) {
return i;
}
}
return -1;
}
var key = findIndex(obj, predicate, context)
console.log("type of KEY " + (typeof key))
console.log("KEY IS " + key)
console.log("OBJ KEY IS " + obj[key])
var keycheck = (key !== void 0 && key !== -1)
if (key !== void 0 && key !== -1) {
console.log("#1 EVALUATING AS TRUE")
} else{
console.log("#1 EVALUATING AS FALSE")
}
if (keycheck) {
console.log("#2 EVALUATING AS TRUE")
} else{
console.log("#2 EVALUATING AS FALSE")
}
}
underscoreFind([,,5], function(obj){return obj !== undefined })
}
}
Output on Mac:
qml: type of KEY number
qml: KEY IS 2
qml: OBJ KEY IS 5
qml: #1 EVALUATING AS TRUE
qml: #2 EVALUATING AS TRUE
Output on Windows:
qml: type of KEY number
qml: KEY IS 2
qml: OBJ KEY IS 5
qml: #1 EVALUATING AS FALSE
qml: #2 EVALUATING AS TRUE
Anybody hit this issue before? What is happening here exactly? How can I trust QML's JS Engine after this?
The original problem have arisen in my original project within a library .js file. I am using underscore.js in my QML project as a .js library, which have worked just fine with Qt 5.6.2 and works just fine with Qt 5.9.4 on Mac, but fails at the _.find(...)
function on Windows, which returns undefined
always. As soon as I rename the function from _.find
to something else like _.underscoreFind
and change void 0
check to check it against undefined
it works.
This is the original implementation of _.find
:
_.find = _.detect = function(obj, predicate, context) {
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
if (key !== void 0 && key !== -1) return obj[key];
};
and this is my modified function, which solves the issue on Windows:
_.underscoreFind = function(obj, predicate, context) {
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
if (key !== undefined && key !== -1) return obj[key];
};
Edit 1:
This issue actually was introduced from Qt 5.6.3, aka 5.6.2 has the expected behavior, but 5.6.3 fails already on the above small test example.