说道QML,不得不先说一下ECMAScript:javascript
ECMAScript语言的标准是由Netscape、Sun、微软、Borland等公司基于JavaScript和JScript锤炼、定义出来的。html
ECMAScript能够为不一样种类的宿主环境提供核心的脚本编程能力。ECMAScript仅仅是一个描述,定义了脚本语言的全部属性、方法和对象。它描述了一下内容:java
其余语言能够以它为基础拓展出新特性,好比QML引入了Qt对象系统中的信号与槽等特点功能。c++
QML有三个核心:正则表达式
因此说学号QML,了解ECMAScript必不可少。在开始了解ECMAScript的基本特性以前,要知道qmlscene能够加载QML文档以达到测试的目的,好比以下测试代码,就能够在Qt命令行界面中以“qmlscene text.qml”的方式显示界面效果:express
/* * text.qml */ import QtQuick 2.2 Rectangle { Component.onCompleted: { // 这里放测试代码 } }
下面开始简单介绍ECMAScript:编程
与C、C++或者Java相似。若是你有这几种语言的基础,那学习ECMAScript简直就是“张飞吃豆芽,小菜一碟”。须要注意的几点是:数组
知道变量area和Area不同就好了,无需多言。函数
ECMAScript语言是弱类型语言,变量没有特定的类型,在定义变量的时候都用var定义,能够用任意值初始化变量,并且能够随时改变变量所存储的数据类型,固然了,最好是不要这么作。工具
ECMAScript中,若是没有以分号结尾,它就会把本行的末尾当作是该语句的结束。以后须要QML与C++混合编程,为了避免思想分裂,故而仍是与c++风格保持一致的好啊,你说是也不是。
与c++中变量声明以及定义是相似的,这里没必要多言。在ECMAScript中,变量能够存放两种类型的值,即原始值和引用值。原始值通常存放在栈上,引用值是一个指针,指向存储在堆中的对象,若是你熟悉c++的话,那么很容易就能理解这个概念。
在ECMAScript中,原始类型有5种:
typeof运算符能够判断一个值的类型,是原始类型会返回类型的名字,是引用类型则统一返回“object”做为类型名字。如下为简单的示例:
/* * typeof value */ import QtQuick 2.2 Rectangle { Component.onCompleted: { var name = "matao"; console.log(typeof name); console.log(typeof 60); } }
Undefined类型和Null类型都只有一个值,即undefined、null。
数字类型的最大值是Number.MAX_VALUE,最小值是Number.MIN_VALUE,它们定义了Number值的外边界,全部的ECMAScript数都必须在这两个值之间。不过,由表达式的值能够不落在这两个数之间。大于最大值,它将被赋值为Number.POSITIVE_INFINITY,即正无穷大;当生成的数值小于Number.MIN_VALUE时,将被赋值为Number.NEGATIVE_INFINITY,即负无穷大。其实,ECMAScript也有专门表示无穷大的值,即Infinity,而-Infinity表示负无穷大。
isFinit()方法能够判断一个数是不是又穷的。
还有一个特殊值NaN,表示非数。isNaN判断一个数是不是非数。
parseInt("2014年"); //2014 parseInt("3.14"); //3 parseFloat("3.13.1"); //3.13 parseInt("INGI"); //NaN
var null2String = String(null); // “null” var oNull = null var s2 = oNull.toString(); // error
首先声明,其实在ECMAScript中并无“类”这个词,与其对应的是“对象定义”,这里的“类”代指的就是这个意思,区别于C++、Java中的类。前面提到的引用值,指向的就是对象。
对象是由new运算符加上要实例化的类型的名字建立的。好比:
var a = new Array();
若是类的构造函数没有参数,括号能够省略。
几个基本的对象:
Object类是全部ECMAScript类的基类,Object类的全部属性和方法都会出如今其余类中:
以上的每种属性和方法均可以被object的派生类覆盖。
关于对象有如下几点须要说明:
1.动态增长属性
在ECMAScript中,对象的属性能够动态地增删,好比下面的示例:
var person = new Object(); person.name = "LingXiaoMo"; person.year = 20;
2.动态增长方法
对象的方法就是一个函数,也能够动态地增长,而后按函数的方式调用,好比下面的示例:
person.printInfo = function printInfo() { console.log("name-" , this.name , "year-" , this.year); } person.printInfo();
3.使用数组下标访问属性和方法
对象的属性和方法竟然可使用数组下标的形式来访问。好比这样:
console.log(person["name"]); // ->person.name person["printInfo"](); // ->person.printInfo()
[]中的东西叫“索引”,这里的索引是字符串,而不是咱们常见的整数。是否是想到了Key-Value(键值对)?
4.使用for...in枚举对象属性
前面咱们提过propertyIsEnumerable()方法能够判断一个对象的属性是否能够枚举。多数自定义属性和方法都是能够枚举的,而内置对象或宿主对象的多数核心属性是不能枚举的。枚举对象属性时咱们使用数组下标法访问对象属性。看以下的示例:
for(var prop in person) { console.log(prop,",",person[prop]); }
5.对象的字面量表示法
前面已经用过数字字面量、字符串字面量:
其实对象也能用字面量表示:
var person = { "name": "LingXiaoMo", "year": 20 }
上面的代码和前面先构造Object再添加属性的方式,获得的是同样的对象。
对象的字面量表示法,语法是这样的:使用一对花括号表示一个对象,其属性以Key:Value对的形式放在其括号内,多个属性之间使用 逗号 分隔;若是一个属性自己是对象,还可使用字面量表示法来嵌套描述。
String、Boolean、Numble都有本身的对象表示法,通常都使用原始值。
你能够这样构造一个String对象:
var str = new String("I\'m a string");
对字符串有如下基本操做:
1.字符串长度
length属性返回字符串中的字符个数:
console.log(str.length);
对于String的原始值,一样能够经过length属性获知字串长度。好比:
console.log("I\'m a string".length);
2.访问单个字符
charAt()方法能够访问指定索引位置的字符;
能够经过数组下标法访问指定位置的字符;
而charCodeAt()方法返回指定位置字符对应的Unicode编码;
下面是简单的示例:
console.log(str.charAt(2)); // 输出m console.log(str[0]); // 输出I console.log(str.charCodeAt(1)); // 输出39
3.查找字串
indexOf()方法从字符串的开头检索子串,lastInderOf()方法从字符串的结尾开始检索子串,它们返回子串在字符串中的位置,若是找不到则返回-1.这两个方法有一个可选参数,指定开始查找的位置;
search()方法用于检索字符串中指定的字符串,或检索与正则表达式相匹配的子字符串。区分大小写,且只能从字符串的开始进行查找;
match()方法可在字符串内检索指定的值,或者寻找匹配指定正则表达式的一个或多个子串。返回一个存放全部符合规则的子串的数组;
注:
上面4种方法都区分大小写。以一个忽略大小写的正则表达式为参数调用search()或match()方法,可实现忽略大小写的查找。
简单的示例:
console.log(str.indexOf("ing",4)); // 输出9 console.log(str.search(/String/)); // 输出-1 console.log(str.search(/String/i)); // 忽略大小写,输出6 console.log(str.match("tri")); // 输出[tri] var numberSource = new String("2014-08-18, I got 96"); var results = numberSource.match(/\d+/g); console.log(results.length); // 输出4 console.log(results); // 输出[2014,08,18,96]
4.字符串比较
使用大于(>)、小于(<)、等于(==)三个运算符比较字符串,使用的是字符的Unicode编码进行比较,忽略了与本地语言环境相关的语义和排序规则。
localeCompare()方法在比较字符串时,默认采用底层操做系统提供的排序规则。等于时返回0,大于时返回1,小于时返回-1。
示例代码片断:
var str1 = "Qt"; var str2 = "qt"; var str3 = "ok"; console.log(str1<str2); // true console.log(str1.localeCompare(str2)); // 1 console.log(str3.localeCompare(str2)); // -1
能够看到第3行和第4行的结果不一致,真使人意外。
5.链接字符串
concat()方法用于链接两个或多个字符串,返回一个新的字符串。
实际中,使用”+“号可能会更方便一些,效果同样。
6.提取子串
提取子串的方法有三个:
注:
上述三个方法均可以不指定第二个参数,如不指定则返回从起始位置到结束的全部字符;
slice()和substring()两个方法的不一样之处在于对负数参数的处理:前者遇到负数时,会应用”从串尾倒数“这种策略,然后者则是把负数看成0来处理。
7.大小写转换
实现大小写转换的有四个方法:
8.字符串替换
replace方法能够实现这个功能。它的第一个参数是一个字符串原始值或者正则表达式,第二个参数是新字符串。
9.使用arg()进行值替换
arg()是Qt C++中的东西,在这里是QML对实现ECMAScript时作的扩充。
arg()的语法是:string arg(value)。其中value能够是数字、字符串、布尔值、对象等,它用于替换发出调用的字符串对象内的%一、%二、%N等占位符;布尔值会被替换为1或0;对于对象,则使用toString()方法转换后的结果来替换对应的占位符。arg()会返回一个新的字符串对象。
示例代码片断:
var expression = "%1 < %2 = %3"; var result = expression.arg(7).arg(8).arg("true");
须要注意的是,String类型的对象是只读的,凡是牵涉到修改的动做,母串自己不会改变。另外,字符串原始值是伪对象,它可使用String类的全部属性和方法。
String类说到这里,再也不多言。
在Qt C++中有QRegExp,在QML中有RegExp,它们是对字符串执行模式匹配的强大工具。
在ECMAScript中支持的两种构造正则表达式的方法:
或RegExp(pattern,attributes)。
关于正则表达式的修饰符、元字符等其余内容,这里暂且略过。
在ECMAScript中数组都是动态的,其大小能够随时变化,并且数组中的元素类型能够不一样。
下面咱们来看看对数组的基本操做:
一、数组的建立
var arrayObj = new Array(); //建立一个数组 var arrayObj = new Array([size]); //建立一个数组并指定长度,注意不是上限,是长度 var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]); //建立一个数组并赋值
要说明的是,虽然第二种方法建立数组指定了长度,但实际上全部状况下数组都是变长的,也就是说即便指定了长度为5,仍然能够将元素存储在规定长度之外的,注意:这时长度会随之改变。
二、数组的元素的访问
var testGetArrValue=arrayObj[1]; //获取数组的元素值 arrayObj[1]= "这是新值"; //给数组元素赋予新的值
三、数组元素的添加
arrayObj. push([item1 [item2 [. . . [itemN ]]]]);// 将一个或多个新元素添加到数组结尾,并返回数组新长度 arrayObj.unshift([item1 [item2 [. . . [itemN ]]]]);// 将一个或多个新元素添加到数组开始,数组中的元素自动后移,返回数组新长度 arrayObj.splice(insertPos,0,[item1[, item2[, . . . [,itemN]]]]);//将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移,返回""。
四、数组元素的删除
arrayObj.pop(); //移除最后一个元素并返回该元素值 arrayObj.shift(); //移除最前一个元素并返回该元素值,数组中元素自动前移 arrayObj.splice(deletePos,deleteCount); //删除从指定位置deletePos开始的指定数量deleteCount的元素,数组形式返回所移除的元素
五、数组的截取和合并
arrayObj.slice(start, [end]); //以数组的形式返回数组的一部分,注意不包括 end 对应的元素,若是省略 end 将复制 start 以后的全部元素 arrayObj.concat([item1[, item2[, . . . [,itemN]]]]); //将多个数组(也能够是字符串,或者是数组和字符串的混合)链接为一个数组,返回链接好的新的数组
六、数组的拷贝
arrayObj.slice(0); //返回数组的拷贝数组,注意是一个新的数组,不是指向 arrayObj.concat(); //返回数组的拷贝数组,注意是一个新的数组,不是指向
七、数组元素的排序
arrayObj.reverse(); //反转元素(最前的排到最后、最后的排到最前),返回数组地址 arrayObj.sort(); //对数组元素排序,返回数组地址
八、数组元素的字符串化
arrayObj.join(separator); //返回字符串,这个字符串将数组的每个元素值链接在一块儿,中间用 separator 隔开。 //toLocaleString 、toString 、valueOf:能够看做是join的特殊用法,不经常使用
数组对象的3个属性:
一、length 属性
Length属性表示数组的长度,即其中元素的个数。由于数组的索引老是由0开始,因此一个数组的上下限分别是:0和length-1。和其余大多数语言不一样的是,ECMAScript数组的length属性是可变的,这一点须要特别注意。当length属性被设置得更大时,整个数组的状态事实上不会发生变化,仅仅是length属性变大;当length属性被设置得比原来小时,则原先数组中索引大于或等于length的元素的值所有被丢失。下面是演示改变length属性的例子:
var arr=[12,23,5,3,25,98,76,54,56,76]; //定义了一个包含10个数字的数组 //显示数组的长度10 arr.length=12; //增大数组的长度 //显示第9个元素的值,为56 arr.length=5; //将数组的长度减小到5,索引等于或超过5的元素被丢弃 //显示第9个元素已经变为"undefined" arr.length=10; //将数组长度恢复为10 //虽然长度被恢复为10,但第9个元素却显示"undefined"
由上面的代码咱们能够清楚的看到length属性的性质。但length对象不只能够显式的设置,它也有可能被隐式修改。ECMAScript中可使用一个未声明过的变量,一样,也可使用一个未定义的数组元素(指索引超过或等于length的元素),这时,length属性的值将被设置为所使用元素 索引的值加1。例以下面的代码:
var arr=[12,23,5,3,25,98,76,54,56,76]; arr[15]=34;
二、prototype 属性
返回对象类型原型的引用。prototype 属性是 object 共有的。
objectName.prototype
objectName 参数是object对象的名称。
说明:用 prototype 属性提供对象的类的一组基本功能。 对象的新实例“继承”赋予该对象原型的操做。
对于数组对象,以如下例子说明prototype 属性的用途。
给数组对象添加返回数组中最大元素值的方法。要完成这一点,声明一个函数,将它加入 Array.prototype, 并使用它。
function array_max() { var i, max = this[0]; for (i = 1; i < this.length; i++) { if (max < this[i]) max = this[i]; } return max; } Array.prototype.max = array_max; var x = new Array(1, 2, 3, 4, 5, 6); var y = x.max();
三、constructor 属性
表示建立对象的函数。
object.constructor //object是对象或函数的名称。
说明:constructor 属性是全部具备 prototype 的对象的成员。constructor 属性保存了对构造特定对象实例的函数的引用。
例如:
x = new String("Hi"); if (x.constructor == String) // 进行处理(条件为真)。
或
function MyFunc { // 函数体。 } y = new MyFunc; if (y.constructor == MyFunc){} // 进行处理(条件为真)。
对于数组来讲:
y = new Array();
关于Math、Data等类型请移驾到Qt帮助模式下,以关键字检索便可!
首先,ECMAScript不支持函数重载,而后咱们再说函数语法。
函数语法以下:
function functionName(arg1,arg2,...,argN) { // 要执行的代码 }
其余的一些运算符、优先级以及循环语句和条件控制语句,这里一律不论,下面说说这个console。
console是和实现ECMAScript的宿主环境相关的一个对象,提供了输出日志信息、断言、计时器、计数器、性能分析等功能。
前面一直使用的console.log()是用来输出调试信息的,console对象提供了多个打印调试信息的方法:
这些方法是调试QML的利器,咱们以console.log()为例来讲明,它能够打印下列信息:
示例代码片断:
console.log("I\'m minor,^_^"); console.log("I\'m ", 16); var array = new Array(10,12,8,"Anna"); console.debug("print array:",array);
还有一个经常使用的功能就是计时器:
简单示例以下:
console.time("控制台计时器一"); for(var i=0;i<1000;i++){ for(var j=0;j<1000;j++){} } console.timeEnd("控制台计时器一");
好,路还在继续,只不过本节到此结束吧!