首页 > 代码库 > JavaScript Host Environment(Qt5)

JavaScript Host Environment(Qt5)

JavaScript Host Environment

[最近在upgradeQt4->Qt5的时候遇到一些JS的问题, 这个文档很好地解释了其中的变化;]

http://qt-project.org/doc/qt-5/qtqml-javascript-hostenvironment.html 

?

QML提供了一个裁剪过的JavaScript Host Environment来开发QML应用; 这个环境和浏览器或者server端如Node.js所提供的host environment有所不同; e.g. QML没有像普通的浏览器环境中一样提供一个window object或者DOM API;


Common Base

就像浏览器或者server端的js环境, QML runtime实现了ECMAScript Language Specification标准; 这提供了由标准定义的所有的built-in的类型的接口, 比如Object, Array和Math; QML runtime实现了第5版的标准, 和浏览器通常的实现版本一样;

标准的ECMAScript built-ins没有显式地在QML文档中注明; 更多细节可参考ECMA-262 5th edition标准或网上许多的在线js教程, 比如W3Schools JavaScript Reference  --JavaScript Objects Reference section; 许多网站专注于浏览器中的js, 所以一些情况下下你可能要仔细检查spec, 以决定是否一个function或object是标准的ECMAScript, 还是特定于这个浏览器环境的; 

就W3Schools来说, JavaScript Objects Reference section包含了标准, 又有浏览器特定的Browser Objects Reference, HTML DOM Objects Reference sections(这些不适用于QML)


QML Global Object

QML JavaScript host environment实现了一定数量的host object和function, 参考QML Global Object

这些host object和function总是可用的, 不管是否有多少个module导入;


JavaScript Objects and Functions

QML引擎支持一系列的JavaScript object, function和property, 参考List of JavaScript Objects and Functions.

注意QML对本地对象做了如下修改:

- arg()函数被加到 String prototype(原型)中;

- Locale-aware(区域感知)转换function加入到 Date和 Number prototype中;


JavaScript Environment Restrictions

QML对JavaScript代码有如下限制:


- JavaScript代码不能修改 global object;

在QML中, global object是constant的 - 已存在的property不能被修改或删除, 而且不能创建新的property;

多数JavaScript程序并不想修改global obejct; 但JavaScript对于undeclared(未声明)的变量的自动创建, 是一种对global object隐式的修改, 这在QML中是被禁止的;

假设一个变量在scope chain(作用范围)里并不存在, 下面的QML代码是非法的:

1
2
3
4
5
// Illegal modification of undeclared variable
a = 1;
for (var ii = 1; ii < 10; ++ii)
    a = a * ii;
console.log("Result: " + a);

稍微修改一下就成为合法代码:

1
2
3
4
var a = 1;
for (var ii = 1; ii < 10; ++ii)
    a = a * ii;
console.log("Result: " + a);

任何对于global object试图修改的动作--不管隐式的还是显式的--都会引起exception(异常); 如果异常uncaught(未捕获), 会打印出一个warning, 其中包含了问题代码的行号;


- Global code在一个reduced(简化的)作用域内运行

在启动时, 如果一个QML文件包含了使用"global"代码的外部JavaScript文件, 它是在一个只包含外部文件本身和global object的作用域内执行的; 就是说, 它没法正常地访问QML object和 property; 

参考 Scope and Naming Resolution: http://qt-project.org/doc/qt-5/qtqml-documents-scope.html 

Global code对本地变量的access(访问)是允许的; 有效的global code的例子:

1
var colors = [ "red""blue""green""orange""purple" ];

访问了QML object的Global code无法正常运行;

1
2
// Invalid global code - the "rootObject" variable is undefined
var initialPosition = { rootObject.x, rootObject.y }

这个限制在QML environment还没完全建立起来的时候就存在; 要在environment设置完成之后运行代码, 参考 JavaScript in Application Startup Code http://qt-project.org/doc/qt-5/qtqml-javascript-expressions.html#javascript-in-application-startup-code 


- 在QML中的大多数context(上下文)中this指针的值一般是undefined

JavaScript中绑定property时支持this关键字; 在其他所有的情况下, QML中的this的值是undefined;

参考一个特定的object, 提供id:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Item {
    width: 200; height: 100
    function mouseAreaClicked(area) {
        console.log("Clicked in area at: " + area.x + ", " + area.y);
    }
    // This will not work because this is undefined
    MouseArea {
        height: 50; width: 200
        onClicked: mouseAreaClicked(this)
    }
    // This will pass area2 to the function
    MouseArea {
        id: area2
        y: 50; height: 50; width: 200
        onClicked: mouseAreaClicked(area2)
    }
}

---JS Host Environ End---YCR

JavaScript Host Environment(Qt5)