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