QS(QQ Script)是小程序的一套脚本语言,结合 QML,可以构建出页面的结构。
提示
以下是一些使用 QS 的简单示例:
<!--qml-->
<qs module="m1">
var msg = "hello world"; module.exports.message = msg;
</qs>
<view>{{m1.message}}</view>
页面输出:
hello world
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4],
},
})
<!--qml-->
<!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
<qs module="m1">
var getMax = function(array) { var max = undefined; for (var i = 0; i <
array.length; ++i) { max = max === undefined ? array[i] : (max >= array[i] ?
max : array[i]); } return max; } module.exports.getMax = getMax;
</qs>
<!-- 调用 qs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view>{{m1.getMax(array)}}</view>
页面输出:
5
QS 代码可以编写在 qml 文件中的 <qs> 标签内,或以 .qs 为后缀名的文件内。
每一个 .qs 文件和 <qs> 标签都是一个单独的模块。
每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。
一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。
在QQ 开发者工具里面,右键可以直接创建 .qs 文件,在其中直接编写 QS 脚本。
示例代码:
// /pages/comm.qs
var foo = "'hello world' from comm.qs"
var bar = function(d) {
return d
}
module.exports = {
foo: foo,
bar: bar,
}
上述例子在 /pages/comm.qs 的文件里面编写了 QS 代码。该 .qs 文件可以被其他的 .qs 文件 或 QML 中的 <qs> 标签引用。
每个 qs 模块均有一个内置的 module 对象。
exports: 通过该属性,可以对外共享本模块的私有变量与函数。示例代码:
// /pages/tools.qs
var foo = "'hello world' from tools.qs"
var bar = function(d) {
return d
}
module.exports = {
FOO: foo,
bar: bar,
}
module.exports.msg = 'some msg'
<!-- page/index/index.qml -->
<qs src="./../tools.qs" module="tools" />
<view>{{tools.msg}}</view>
<view>{{tools.bar(tools.FOO)}}</view>
页面输出:
some msg
'hello world' from tools.qs
在.qs模块中引用其他 qs 文件模块,可以使用 require 函数。
引用的时候,要注意如下几点:
.qs 文件模块,且必须使用相对路径。qs 模块均为单例,qs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 qs 模块对象。qs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。示例代码:
// /pages/tools.qs
var foo = "'hello world' from tools.qs"
var bar = function(d) {
return d
}
module.exports = {
FOO: foo,
bar: bar,
}
module.exports.msg = 'some msg'
// /pages/logic.qs
var tools = require('./tools.qs')
console.log(tools.FOO)
console.log(tools.bar('logic.qs'))
console.log(tools.msg)
<!-- /page/index/index.qml -->
<qs src="./../logic.qs" module="logic" />
控制台输出:
'hello world' from tools.qs
logic.qs
some msg
<qs> 标签| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| module | String | 当前 <qs> 标签的模块名。必填字段。 | |
| src | String | 引用 .qs 文件的相对路径。仅当本标签为单闭合标签或标签的内容为空时有效。 |
module 属性是当前 <qs> 标签的模块名。在单个 qml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 qs 模块名不会相互覆盖。
module 属性值的命名必须符合下面两个规则:
示例代码:
<!--qml-->
<qs module="foo">
var some_msg = "hello world"; module.exports = { msg : some_msg, }
</qs>
<view>{{foo.msg}}</view>
页面输出:
hello world
上面例子声明了一个名字为 foo 的模块,将 some_msg 变量暴露出来,供当前页面使用。
src 属性可以用来引用其他的 qs 文件模块。
引用的时候,要注意如下几点:
.qs 文件模块,且必须使用相对路径。qs 模块均为单例,qs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 qs 模块对象。qs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。示例代码:
// /pages/index/index.js
Page({
data: {
msg: "'hello wrold' from js",
},
})
<!-- /pages/index/index.qml -->
<qs src="./../comm.qs" module="some_comms"></qs>
<!-- 也可以直接使用单标签闭合的写法
<qs src="./../comm.qs" module="some_comms" />
-->
<!-- 调用 some_comms 模块里面的 bar 函数,且参数为 some_comms 模块里面的 foo -->
<view>{{some_comms.bar(some_comms.foo)}}</view>
<!-- 调用 some_comms 模块里面的 bar 函数,且参数为 page/index/index.js 里面的 msg -->
<view>{{some_comms.bar(msg)}}</view>
页面输出:
'hello world' from comm.qs
'hello wrold' from js
上述例子在文件 /page/index/index.qml 中通过 <qs> 标签引用了 /page/comm.qs 模块。
<qs> 模块只能在定义模块的 QML 文件中被访问到。使用 <include> 或 <import> 时,<qs> 模块不会被引入到对应的 QML 文件中。<template> 标签中,只能使用定义该 <template> 的 QML 文件中定义的 <qs> 模块。undefined。var foo = 1
var bar = 'hello world'
var i // i === undefined
上面代码,分别声明了 foo、 bar、 i 三个变量。然后,foo 赋值为数值 1 ,bar 赋值为字符串 "hello world"。
变量命名必须符合下面两个规则:
以下标识符不能作为变量名:
delete
void
typeof
null
undefined
NaN
Infinity
var
if
else
true
false
require
this
function
arguments
return
for
while
do
break
continue
switch
case
default
QS 主要有 3 种注释的方法。
示例代码:
<!-- qml -->
<qs module="sample">
// 方法一:单行注释 /* 方法二:多行注释 */ /* 方法三:结尾注释。即从 /*
开始往后的所有 QS 代码均被注释 var a = 1; var b = 2; var c = "fake";
</qs>
上述例子中,所有 QS 代码均被注释掉了。
方法三 和 方法二 的唯一区别是,没有
*/结束符。
示例代码:
var a = 10,
b = 20
// 加法运算
console.log(30 === a + b)
// 减法运算
console.log(-10 === a - b)
// 乘法运算
console.log(200 === a * b)
// 除法运算
console.log(0.5 === a / b)
// 取余运算
console.log(10 === a % b)
+)也可以用作字符串的拼接。var a = '.q',
b = 's'
// 字符串拼接
console.log('.qs' === a + b)
示例代码:
var a = 10,
b = 20
// 自增运算
console.log(10 === a++)
console.log(12 === ++a)
// 自减运算
console.log(12 === a--)
console.log(10 === --a)
// 正值运算
console.log(10 === +a)
// 负值运算
console.log(0 - 10 === -a)
// 否运算
console.log(-11 === ~a)
// 取反运算
console.log(false === !a)
// delete 运算
console.log(true === delete a.fake)
// void 运算
console.log(undefined === void a)
// typeof 运算
console.log('number' === typeof a)
示例代码:
var a = 10,
b = 20
// 左移运算
console.log(80 === a << 3)
// 无符号右移运算
console.log(2 === a >> 2)
// 带符号右移运算
console.log(2 === a >>> 2)
// 与运算
console.log(2 === (a & 3))
// 异或运算
console.log(9 === (a ^ 3))
// 或运算
console.log(11 === (a | 3))
示例代码:
var a = 10,
b = 20
// 小于
console.log(true === a < b)
// 大于
console.log(false === a > b)
// 小于等于
console.log(true === a <= b)
// 大于等于
console.log(false === a >= b)
示例代码:
var a = 10,
b = 20
// 等号
console.log(false === (a == b))
// 非等号
console.log(true === (a != b))
// 全等号
console.log(false === (a === b))
// 非全等号
console.log(true === (a !== b))
示例代码:
var a = 10
a = 10
a *= 10
console.log(100 === a)
a = 10
a /= 5
console.log(2 === a)
a = 10
a %= 7
console.log(3 === a)
a = 10
a += 5
console.log(15 === a)
a = 10
a -= 11
console.log(-1 === a)
a = 10
a <<= 10
console.log(10240 === a)
a = 10
a >>= 2
console.log(2 === a)
a = 10
a >>>= 2
console.log(2 === a)
a = 10
a &= 3
console.log(2 === a)
a = 10
a ^= 3
console.log(9 === a)
a = 10
a |= 3
console.log(11 === a)
示例代码:
var a = 10,
b = 20
// 逻辑与
console.log(20 === (a && b))
// 逻辑或
console.log(10 === (a || b))
示例代码:
var a = 10,
b = 20
//条件运算符
console.log(20 === (a >= 10 ? a + 10 : b + 10))
//逗号运算符
console.log(20 === (a, b))
| 优先级 | 运算符 | 说明 | 结合性 |
|---|---|---|---|
| 20 | ( ... ) | 括号 | n/a |
| 19 | ... . ... | 成员访问 | 从左到右 |
... [ ... ] | 成员访问 | 从左到右 | |
... ( ... ) | 函数调用 | 从左到右 | |
| 17 | ... ++ | 后置递增 | n/a |
... -- | 后置递减 | n/a | |
| 16 | ! ... | 逻辑非 | 从右到左 |
~ ... | 按位非 | 从右到左 | |
+ ... | 一元加法 | 从右到左 | |
- ... | 一元减法 | 从右到左 | |
++ ... | 前置递增 | 从右到左 | |
-- ... | 前置递减 | 从右到左 | |
typeof ... | typeof | 从右到左 | |
void ... | void | 从右到左 | |
delete ... | delete | 从右到左 | |
| 14 | ... * ... | 乘法 | 从左到右 |
... / ... | 除法 | 从左到右 | |
... % ... | 取模 | 从左到右 | |
| 13 | ... + ... | 加法 | 从左到右 |
... - ... | 减法 | 从左到右 | |
| 12 | ... << ... | 按位左移 | 从左到右 |
... >> ... | 按位右移 | 从左到右 | |
... >>> ... | 无符号右移 | 从左到右 | |
| 11 | ... < ... | 小于 | 从左到右 |
... <= ... | 小于等于 | 从左到右 | |
... > ... | 大于 | 从左到右 | |
... >= ... | 大于等于 | 从左到右 | |
| 10 | ... == ... | 等号 | 从左到右 |
... != ... | 非等号 | 从左到右 | |
... === ... | 全等号 | 从左到右 | |
... !== ... | 非全等号 | 从左到右 | |
| 9 | ... & ... | 按位与 | 从左到右 |
| 8 | ... ^ ... | 按位异或 | 从左到右 |
| 7 | ... | ... | 按位或 | 从左到右 |
| 6 | ... && ... | 逻辑与 | 从左到右 |
| 5 | ... || ... | 逻辑或 | 从左到右 |
| 4 | ... ? ... : ... | 条件运算符 | 从右到左 |
| 3 | ... = ... | 赋值 | 从右到左 |
... += ... | 赋值 | 从右到左 | |
... -= ... | 赋值 | 从右到左 | |
... *= ... | 赋值 | 从右到左 | |
... /= ... | 赋值 | 从右到左 | |
... %= ... | 赋值 | 从右到左 | |
... <<= ... | 赋值 | 从右到左 | |
... >>= ... | 赋值 | 从右到左 | |
... >>>= ... | 赋值 | 从右到左 | |
... &= ... | 赋值 | 从右到左 | |
... ^= ... | 赋值 | 从右到左 | |
... |= ... | 赋值 | 从右到左 | |
| 0 | ... , ... | 逗号 | 从左到右 |
在 QS 中,可以使用以下格式的 if 语句 :
if (expression) statement : 当 expression 为 truthy 时,执行 statement。
if (expression) statement1 else statement2 : 当 expression 为 truthy 时,执行 statement1。 否则,执行 statement2
if ... else if ... else statementN 通过该句型,可以在 statement1 ~ statementN 之间选其中一个执行。
示例语法:
// if ...
if (表达式) 语句
if (表达式) 语句
if (表达式) {
代码块
}
// if ... else
if (表达式) 语句
else 语句
if (表达式) 语句
else 语句
if (表达式) {
代码块
} else {
代码块
}
// if ... else if ... else ...
if (表达式) {
代码块
} else if (表达式) {
代码块
} else if (表达式) {
代码块
} else {
代码块
}
示例语法:
switch (表达式) {
case 变量:
语句
case 数字:
语句
break
case 字符串:
语句
default:
语句
}
default 分支可以省略不写。case 关键词后面只能使用:变量,数字,字符串。示例代码:
var exp = 10
switch (exp) {
case '10':
console.log('string 10')
break
case 10:
console.log('number 10')
break
case exp:
console.log('var exp')
break
default:
console.log('default')
}
输出:
number 10
示例语法:
for (语句; 语句; 语句) 语句
for (语句; 语句; 语句) {
代码块
}
break,continue 关键词。示例代码:
for (var i = 0; i < 3; ++i) {
console.log(i)
if (i >= 1) break
}
输出:
0
1
示例语法:
while (表达式) 语句
while (表达式) {
代码块
}
do {
代码块
} while (表达式)
表达式为 true 时,循环执行语句或代码块。break,continue 关键词。QS 语言目前共有以下几种数据类型:
number : 数值string :字符串boolean:布尔值object:对象function:函数array : 数组date:日期regexp:正则number 包括两种数值:整数,小数。
var a = 10
var PI = 3.141592653589793
constructor:返回字符串 "Number"。toStringtoLocaleStringvalueOftoFixedtoExponentialtoPrecision以上方法的具体使用请参考
ES5标准。
string 有两种写法:
'hello world'
'hello world'
constructor:返回字符串 "String"。length除 constructor 外属性的具体含义请参考
ES5标准。
toStringvalueOfcharAtcharCodeAtconcatindexOflastIndexOflocaleComparematchreplacesearchslicesplitsubstringtoLowerCasetoLocaleLowerCasetoUpperCasetoLocaleUpperCasetrim以上方法的具体使用请参考
ES5标准。
布尔值只有两个特定的值:true 和 false。
constructor:返回字符串 "Boolean"。toStringvalueOf以上方法的具体使用请参考
ES5标准。
object 是一种无序的键值对。使用方法如下所示:
var o = {} //生成一个新的空对象
//生成一个新的非空对象
o = {
string: 1, //object 的 key 可以是字符串
const_var: 2, //object 的 key 也可以是符合变量定义规则的标识符
func: {}, //object 的 value 可以是任何类型
}
//对象属性的读操作
console.log(1 === o['string'])
console.log(2 === o.const_var)
//对象属性的写操作
o['string']++
o['string'] += 10
o.const_var++
o.const_var += 10
//对象属性的读操作
console.log(12 === o['string'])
console.log(13 === o.const_var)
constructor:返回字符串 "Object"。console.log('Object' === { k: '1', v: '2' }.constructor)
toString:返回字符串 "[object Object]"。function 支持以下的定义方式:
//方法 1
function a(x) {
return x
}
//方法 2
var b = function(x) {
return x
}
function 同时也支持以下的语法(匿名函数,闭包等):
var a = function(x) {
return function() {
return x
}
}
var b = a(100)
console.log(100 === b())
function 里面可以使用 arguments 关键词。该关键词目前只支持以下的属性:
length: 传递给函数的参数个数。[index]: 通过 index 下标可以遍历传递给函数的每个参数。示例代码:
var a = function() {
console.log(3 === arguments.length)
console.log(100 === arguments[0])
console.log(200 === arguments[1])
console.log(300 === arguments[2])
}
a(100, 200, 300)
constructor:返回字符串 "Function"。length:返回函数的形参个数。toString:返回字符串 "[function Function]"。示例代码:
var func = function(a, b, c) {}
console.log('Function' === func.constructor)
console.log(3 === func.length)
console.log('[function Function]' === func.toString())
array 支持以下的定义方式:
var a = [] //生成一个新的空数组
a = [1, '2', {}, function() {}] //生成一个新的非空数组,数组元素可以是任何类型
constructor:返回字符串 "Array"。length除 constructor 外属性的具体含义请参考
ES5标准。
toStringconcatjoinpoppushreverseshiftslicesortspliceunshiftindexOflastIndexOfeverysomeforEachmapfilterreducereduceRight以上方法的具体使用请参考
ES5标准。
生成 date 对象需要使用 getDate函数, 返回一个当前时间的对象。
getDate()
getDate(milliseconds)
getDate(datestring)
getDate(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]])
milliseconds: 从 1970 年 1 月 1 日 00:00:00 UTC 开始计算的毫秒数datestring: 日期字符串,其格式为:"month day, year hours:minutes:seconds"示例代码:
var date = getDate() //返回当前时间对象
date = getDate(1500000000000)
// Fri Jul 14 2017 10:40:00 GMT+0800 (中国标准时间)
date = getDate('2017-7-14')
// Fri Jul 14 2017 00:00:00 GMT+0800 (中国标准时间)
date = getDate(2017, 6, 14, 10, 40, 0, 0)
// Fri Jul 14 2017 10:40:00 GMT+0800 (中国标准时间)
constructor:返回字符串 “Date”。toStringtoDateStringtoTimeStringtoLocaleStringtoLocaleDateStringtoLocaleTimeStringvalueOfgetTimegetFullYeargetUTCFullYeargetMonthgetUTCMonthgetDategetUTCDategetDaygetUTCDaygetHoursgetUTCHoursgetMinutesgetUTCMinutesgetSecondsgetUTCSecondsgetMillisecondsgetUTCMillisecondsgetTimezoneOffsetsetTimesetMillisecondssetUTCMillisecondssetSecondssetUTCSecondssetMinutessetUTCMinutessetHourssetUTCHourssetDatesetUTCDatesetMonthsetUTCMonthsetFullYearsetUTCFullYeartoUTCStringtoISOStringtoJSON以上方法的具体使用请参考
ES5标准。
生成 regexp 对象需要使用 getRegExp函数。
getRegExp(pattern[, flags])
pattern: 正则表达式的内容。flags:修饰符。该字段只能包含以下字符:
g: globali: ignoreCasem: multiline。示例代码:
var a = getRegExp('x', 'img')
console.log('x' === a.source)
console.log(true === a.global)
console.log(true === a.ignoreCase)
console.log(true === a.multiline)
constructor:返回字符串 "RegExp"。sourceglobalignoreCasemultilinelastIndex除 constructor 外属性的具体含义请参考
ES5标准。
exectesttoString以上方法的具体使用请参考
ES5标准。
constructor 属性数据类型的判断可以使用 constructor 属性。
示例代码:
var number = 10
console.log('Number' === number.constructor)
var string = 'str'
console.log('String' === string.constructor)
var boolean = true
console.log('Boolean' === boolean.constructor)
var object = {}
console.log('Object' === object.constructor)
var func = function() {}
console.log('Function' === func.constructor)
var array = []
console.log('Array' === array.constructor)
var date = getDate()
console.log('Date' === date.constructor)
var regexp = getRegExp()
console.log('RegExp' === regexp.constructor)
typeof使用 typeof 也可以区分部分数据类型。
示例代码:
var number = 10
var boolean = true
var object = {}
var func = function() {}
var array = []
var date = getDate()
var regexp = getRegExp()
console.log('number' === typeof number)
console.log('boolean' === typeof boolean)
console.log('object' === typeof object)
console.log('function' === typeof func)
console.log('object' === typeof array)
console.log('object' === typeof date)
console.log('object' === typeof regexp)
console.log('undefined' === typeof undefined)
console.log('object' === typeof null)
console.log 方法用于在 console 窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。
ELN10LN2LOG2ELOG10EPISQRT1_2SQRT2以上属性的具体使用请参考
ES5标准。
absacosasinatanatan2ceilcosexpfloorlogmaxminpowrandomroundsinsqrttan以上方法的具体使用请参考
ES5标准。
stringify(object): 将 object 对象转换为 JSON 字符串,并返回该字符串。parse(string): 将 JSON 字符串转化成对象,并返回该对象。示例代码:
console.log(undefined === JSON.stringify())
console.log(undefined === JSON.stringify(undefined))
console.log('null' === JSON.stringify(null))
console.log('111' === JSON.stringify(111))
console.log('"111"' === JSON.stringify('111'))
console.log('true' === JSON.stringify(true))
console.log(undefined === JSON.stringify(function() {}))
console.log(undefined === JSON.parse(JSON.stringify()))
console.log(undefined === JSON.parse(JSON.stringify(undefined)))
console.log(null === JSON.parse(JSON.stringify(null)))
console.log(111 === JSON.parse(JSON.stringify(111)))
console.log('111' === JSON.parse(JSON.stringify('111')))
console.log(true === JSON.parse(JSON.stringify(true)))
console.log(undefined === JSON.parse(JSON.stringify(function() {})))
MAX_VALUEMIN_VALUENEGATIVE_INFINITYPOSITIVE_INFINITY以上属性的具体使用请参考
ES5标准。
parseUTCnow以上属性的具体使用请参考
ES5标准。
NaNInfinityundefined以上属性的具体使用请参考
ES5标准。
parseIntparseFloatisNaNisFinitedecodeURIdecodeURIComponentencodeURIencodeURIComponent以上方法的具体使用请参考
ES5标准。