JavaScript Host Environment

QML提供了一个JavaScript主机环境, 专门用于编写QML应用程序. 此环境与浏览器或服务器端JavaScript环境(如Node.js)提供的主机环境不同. 例如, QML不提供浏览器环境中常见的window对象或DOM API.

公共基础

与浏览器或服务器端JavaScript环境一样, QML运行时实现ECMAScript语言规范标准. QML提供了对标准定义的所有内置类型和函数的访问, 如Object, Array和Math. QML运行时实现了该标准的第7版.Nullish Coalescing(从Qt 5.15起)和 Optional Chaining(从Qt 6.2起)也在QML运行时中实现.

QML文档中没有明确记录标准ECMAScript, 参见参阅ECMA-262第7版标准或众多在线JavaScript参考和教程网站,如W3Schools JavaScript Reference 章节). 许多网站都关注浏览器中的JavaScript, 因此, 某些情况下, 你可能需要仔细检查规范, 以确定给定的函数或对象是标准ECMAScript的一部分, 还是特定于浏览器环境. 在W3Schools网站上, JavaScript Objects Reference 章节通常涵盖标准, 而Browser Objects ReferenceHTML DOM Objects Reference章节是特定于浏览器的(因此不适用于QML).

QML全局对象

QML JavaScript主机环境实现了许多主机对象和函数, 详见QML Global Object.

无论是否导入任何模块, 这些主机对象和函数始终可用.

JavaScript对象和函数

QML引擎支持的JavaScript对象, 函数和属性参见List of JavaScript Objects and Functions.

注意: QML对本机对象进行如下修改:

JavaScript环境限制

QML对JavaScript代码实现以下限制:

  • .qml文件中的JavaScript代码不能修改全局对象. .js文件中的JavaScript代码可以修改全局对象, 这些修改在imported时, 对.qml文件可见.

    在QML中, 如果全局对象是常量, 不能修改或删除现有属性, 也不能创建新属性.

    多数JavaScript程序不会有意修改全局对象. 然而, JavaScript自动创建未声明的变量, 是对全局对象的隐式修改, 这种行为在QML被禁止.

    如下所示, 假设变量a在作用域不存在, 这段代码在QML中是非法的:

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

    上面代码可以简单修改.

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

    任何修改全局对象的尝试(无论是隐式还是显式)都将抛出异常. 如果异常未捕获, 将打印一个警告, 包含问题代码的文件和行号.

  • 全局代码在缩小的范围内运行.

    启动期间, 如果QML文件包含带有"全局"代码的外部JavaScript文件, 则它将在仅包含外部文件本身和全局对象的范围内执行. 也就是说, 它将无法正常访问QML对象和属性.

    全局代码仅允许访问脚本局部变量. 如下所示, 一个有效的全局代码.

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

    全局代码访问QML对象无法正确执行.

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

    由于QML环境尚未完全建立, 因此存在此限制. 在环境设置完成后运行代码. 参见 JavaScript in Application Startup Code.

  • 在QML的多数上下文中, this是未定义的. JavaScript属性绑定时, 支持this关键字. 在QML绑定表达式, QML信号处理程序和QML声明的函数中, this指作用域对象. 其他情况下, this是未定义的.

    使用id引用特定对象. 例如:

    
      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)
          }
      }