小程式開發之指令碼語言WXS
WXS
WXS(WeiXin Script)是小程式的一套指令碼語言
,結合 WXML,可以構建出頁面的結構。
注意
- wxs 不依賴於執行時的基礎庫版本,可以在所有版本的小程式中執行。
- wxs 與 javascript 是不同的語言,有自己的語法,並不和 javascript 一致。
- wxs 的執行環境和其他 javascript 程式碼是隔離的,wxs 中不能呼叫其他 javascript 檔案中定義的函式,也不能呼叫小程式提供的API。
- wxs 函式不能作為元件的事件回撥。
- 由於執行環境的差異,在 iOS 裝置上小程式內的 wxs 會比 javascript 程式碼快 2 ~ 20 倍。在 android 裝置上二者執行效率無差異。
以下是一些使用 WXS 的簡單示例
頁面渲染
index.wxml
<!--wxml-->
<wxs module="m1">var msg = "hello world"; module.exports.message = msg;</wxs>
<view>{{m1.message}}</view>
解析:頁面輸出:hello world
資料處理
index.js
// page.js Page({ data: { array: [1, 2, 3, 4, 5, 1, 2, 3, 4] } })
index.wxml
<!--wxml--> <!-- 下面的 getMax 函式,接受一個數組,且返回陣列中最大的元素的值 --> <wxs 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; </wxs> <!-- 呼叫 wxs 裡面的 getMax 函式,引數為 page.js 裡面的 array --> <view>{{m1.getMax(array)}}</view>
解析:頁面輸出:5
WXS 模組
WXS 程式碼可以編寫在 wxml 檔案中的 標籤內,或以 .wxs 為字尾名的檔案內。
模組
每一個 .wxs 檔案和 標籤都是一個單獨的模組。
每個模組都有自己獨立的作用域。即在一個模組裡面定義的變數與函式,預設為私有的,對其他模組不可見。
一個模組要想對外暴露其內部的私有變數與函式,只能通過 module.exports 實現。
.wxs 檔案
在微信開發者工具裡面,右鍵可以直接建立 .wxs 檔案,在其中直接編寫 WXS 指令碼。
示例程式碼:
index.wxs
// /pages/index.wxs
var foo = "'hello world' from comm.wxs";
var bar = function (d) {
return d;
}
module.exports = {
foo: foo,
bar: bar
};
上述例子在 /pages//index.wxs 的檔案裡面編寫了 WXS 程式碼。該 .wxs 檔案可以被其他的 .wxs 檔案 或 WXML 中的 標籤引用。
module 物件
每個 wxs 模組均有一個內建的 module
物件。
exports – module 物件屬性
exports
: 通過該屬性,可以對外共享本模組的私有變數與函式。
例如:
tools.wxs
// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
return d;
}
module.exports = {
FOO: foo,
bar: bar,
};
module.exports.msg = "some msg";
index.wxml
<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view>{{tools.msg}}</view>
<view>{{tools.bar(tools.FOO)}}</view>
解析:頁面輸出:
some msg
‘hello world’ from tools.wxs
require函式
在.wxs模組中引用其他 wxs 檔案模組,可以使用 require 函式。
引用的時候,要注意如下幾點:
- 只能引用 .wxs 檔案模組,且必須使用相對路徑。
- wxs 模組均為單例,wxs 模組在第一次被引用時,會自動初始化為單例物件。多個頁面,多個地方,多次引用,使用的都是同一個 wxs 模組物件。
- 如果一個 wxs 模組在定義之後,一直沒有被引用,則該模組不會被解析與執行。
示例程式碼:
tools.wxs
// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
return d;
}
module.exports = {
FOO: foo,
bar: bar,
};
module.exports.msg = "some msg";
logic.wxs
// /pages/logic.wxs
var tools = require("./tools.wxs");
console.log(tools.FOO);
console.log(tools.bar("logic.wxs"));
console.log(tools.msg);
index.wxml
<!-- /page/index/index.wxml -->
<wxs src="./../logic.wxs" module="logic" />
解析:控制檯輸出:
‘hello world’ from tools.wxs
logic.wxs
some msg
標籤
module 屬性
module 屬性是當前 標籤的模組名。在單個 wxml 檔案內,建議其值唯一。有重複模組名則按照先後順序覆蓋(後者覆蓋前者)。不同檔案之間的 wxs 模組名不會相互覆蓋。
module 屬性值的命名必須符合下面兩個規則:
- 首字元必須是:字母(a-zA-Z),下劃線(_)
- 剩餘字元可以是:字母(a-zA-Z),下劃線(_), 數字(0-9)
index.wxml
<!--wxml-->
<wxs module="foo">
var some_msg = "hello world"; module.exports = { msg : some_msg, }
</wxs>
<view>{{foo.msg}}</view>
解析:頁面輸出:
hello world
上面例子聲明瞭一個名字為 foo 的模組,將 some_msg 變數暴露出來,供當前頁面使用。
src 屬性
src 屬性可以用來引用其他的 wxs 檔案模組。
引用的時候,要注意如下幾點:
只能引用 .wxs 檔案模組,且必須使用相對路徑。
wxs 模組均為單例,wxs 模組在第一次被引用時,會自動初始化為單例物件。多個頁面,多個地方,多次引用,使用的都是同一個 wxs 模組物件。
如果一個 wxs 模組在定義之後,一直沒有被引用,則該模組不會被解析與執行。
index.js
// /pages/index/index.js
Page({
data: {
msg: "'hello wrold' from js",
}
})
index.wxml
<!-- /pages/index/index.wxml -->
<wxs src="./../comm.wxs" module="some_comms"></wxs>
<!-- 也可以直接使用單標籤閉合的寫法
<wxs src="./../comm.wxs" 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.wxs
‘hello wrold’ from js
上述例子在檔案 /page/index/index.wxml 中通過 標籤引用了 /page/comm.wxs 模組。
注意
(1) 模組只能在定義模組的 WXML 檔案中被訪問到。使用 或 時, 模組不會被引入到對應的 WXML 檔案中。
(2) 標籤中,只能使用定義該 的 WXML 檔案中定義的 模組。
變數
變數概念
- WXS 中的變數均為值的引用。
- 沒有宣告的變數直接賦值使用,會被定義為全域性變數。
- 如果只宣告變數而不賦值,則預設值為 undefined。
- var表現與javascript一致,會有變數提升。
舉例:
var foo = 1;
var bar = “hello world”;
var i; // i === undefined
上面程式碼,分別聲明瞭 foo、 bar、 i 三個變數。然後,foo 賦值為數值 1 ,bar 賦值為字串 “hello world”,i 預設值為 undefined。
變數名
變數命名必須符合下面兩個規則:
- 首字元必須是:字母(a-zA-Z),下劃線(_)
- 剩餘字元可以是:字母(a-zA-Z),下劃線(_), 數字(0-9)
保留識別符號
以下識別符號不能作為變數名:
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
運算子
提前說一下
==
:等同,比較運算子,兩邊值型別不同的時候,先進行型別轉換,再比較;
===
:恆等,嚴格比較運算子,不做型別轉換,型別不同就是不等;
基本運算子
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 = '.w', b = 'xs';
// 字串拼接
console.log('.wxs' === 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));
運算子優先順序
語句
if 語句
在 WXS 中,可以使用以下格式的 if 語句 :
- if (expression) statement : 當 expression 為 truthy 時,執行 statement。
- if (expression) statement1 else statement2 : 當 expression 為 truthy 時,執行 statement1。 否則,執行 statement2
- if … else if … else statementN 通過該句型,可以在 statement1 ~ statementN 之間選其中一個執行。
if … else
if (表示式) 語句;
else 語句;
if (表示式)
語句;
else
語句;
if (表示式) {
程式碼塊;
} else {
程式碼塊;
}
if … else if … else …
if (表示式) {
程式碼塊;
} else if (表示式) {
程式碼塊;
} else if (表示式) {
程式碼塊;
} else {
程式碼塊;
}
switch 語句
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 (語句; 語句; 語句)
語句;
for (語句; 語句; 語句) {
程式碼塊;
}
支援使用 break,continue 關鍵詞。
break
語句可用於跳出迴圈。break所在的迴圈體已經結束。continue
語句中斷迴圈中的迭代,如果出現了指定的條件,然後繼續迴圈中的下一個迭代。continue所在的迴圈體並沒有結束。
for (var i = 0; i < 3; ++i) {
console.log(i);
if (i >= 1) break;
}
解析:控制檯輸出:
0
1
while 語句
while (表示式)
語句;
while (表示式) {
程式碼塊;
}
do {
程式碼塊;
} while (表示式)
- 當表示式為 true 時,迴圈執行語句或程式碼塊。
- 支援使用 break,continue 關鍵詞。
註釋
WXS 主要有 3 種註釋的方法。
方法一:單行註釋 /*
方法二:多行註釋 / /
方法三:結尾註釋。即從 /*
<!--wxml -->
<wxs module="sample" >
// 方法一:單行註釋 /* 方法二:多行註釋 */ /* 方法三:結尾註釋。即從 /*
開始往後的所有 WXS 程式碼均被註釋 var a = 1; var b = 2; var c = "fake";
</wxs>
資料型別
WXS 語言目前共有以下幾種資料型別:
number
: 數值string
:字串boolean
:布林值object
:物件function
:函式array
: 陣列date
:日期regexp
:正則
number : 數值
語法
number 包括兩種數值:整數,小數。
var a = 10;
var PI = 3.141592653589793;
屬性
constructor
:返回字串 “Number”。
方法
- toString
- toLocaleString
- valueOf
- toFixed
- toExponential
- toPrecision
以上方法的具體使用請參考 ES5 標準。
string :字串
語法
string 有兩種寫法:
'hello world';
"hello world";
屬性
constructor
:返回字串 “String”。
length
: 字串長度
除constructor外屬性的具體含義請參考 ES5 標準。
方法
toString
valueOf
charAt
charCodeAt
concat
indexOf
lastIndexOf
localeCompare
match
replace
search
slice
split
substring
toLowerCase
toLocaleLowerCase
toUpperCase
toLocaleUpperCase
trim
以上方法的具體使用請參考 ES5 標準。
boolean:布林值
語法
布林值只有兩個特定的值:true 和 false。
屬性
constructor
:返回字串 “Boolean”。
方法
toString
valueOf
以上方法的具體使用請參考 ES5 標準。
object:物件
語法
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:函式
語法
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() );
arguments
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 : 陣列
語法
array 支援以下的定義方式:
var a = []; //生成一個新的空陣列
a = [1,"2",{},function(){}]; //生成一個新的非空陣列,陣列元素可以是任何型別
屬性
constructor
:返回字串 “Array”。
length
: 陣列數量
除constructor外屬性的具體含義請參考 ES5 標準。
方法
toString
concat
join
pop
push
reverse
shift
slice
sort
splice
unshift
indexOf
lastIndexOf
every
some
forEach
map
filter
reduce
reduceRight
以上方法的具體使用請參考 ES5 標準。
date:日期
語法
生成 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”。
方法
toString
toDateString
toTimeString
toLocaleString
toLocaleDateString
toLocaleTimeString
valueOf
getTime
getFullYear
getUTCFullYear
getMonth
getUTCMonth
getDate
getUTCDate
getDay
getUTCDay
getHours
getUTCHours
getMinutes
getUTCMinutes
getSeconds
getUTCSeconds
getMilliseconds
getUTCMilliseconds
getTimezoneOffset
setTime
setMilliseconds
setUTCMilliseconds
setSeconds
setUTCSeconds
setMinutes
setUTCMinutes
setHours
setUTCHours
setDate
setUTCDate
setMonth
setUTCMonth
setFullYear
setUTCFullYear
toUTCString
toISOString
toJSON
以上方法的具體使用請參考 ES5 標準。
regexp:正則
語法
生成 regexp 物件需要使用 getRegExp函式。
getRegExp(pattern[, flags])
引數:
pattern: 正則表示式的內容。
flags:修飾符。該欄位只能包含以下字元:
g: global
i: ignoreCase
m: 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”。
source
global
ignoreCase
multiline
lastIndex
除constructor外屬性的具體含義請參考 ES5 標準。
方法
exec
test
toString
以上方法的具體使用請參考 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
console.log 方法用於在 console 視窗輸出資訊。它可以接受多個引數,將它們的結果連線起來輸出。
Math
屬性
E
LN10
LN2
LOG2E
LOG10E
PI
SQRT1_2
SQRT2
以上方法的具體使用請參考 ES5 標準。
方法
abs
acos
asin
atan
atan2
ceil
cos
exp
floor
log
max
min
pow
random
round
sin
sqrt
tan
以上方法的具體使用請參考 ES5 標準。
JSON
方法
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(){})));
Number
屬性
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
POSITIVE_INFINITY
以上方法的具體使用請參考 ES5 標準。
Date
屬性
parse
UTC
now
以上方法的具體使用請參考 ES5 標準。
Global
屬性
NaN
Infinity
undefined
以上方法的具體使用請參考 ES5 標準。
方法
parseInt
parseFloat
isNaN
isFinite
decodeURI
decodeURIComponent
encodeURI
encodeURIComponent
以上方法的具體使用請參考 ES5 標準。