WMLScript脚本程序设计

  作为一种编辑语言,WMLScript提供了强大的函数、语句和库功能,以及外部编辑、访问控制等支持,同时对程序运行中可能产生的错误给出了检测手段和具体的解决办法。这些内容属于WMLScript的脚本程序设计知识和进一步的编程规定,我们本章就对此进行详细介绍。

  5.1 语句

  前面我们学习了变量、操作符和表达式,但仅由这些内容并不能完成某个完整的功能,因为他们不能形成完整的操作或处理程序。变量就如同与严重的单词,表达式如语言中的词组,他们都不能表达一个完整的意思;只有语句,是语言中完整的句子,能够表达完整的意思并实现某个完整的功能。WML Script提供了丰富的语句功能,使用这些语句我们可以在WML的卡片中建立交互功能和其他需要的复杂功能。

  在WML Script中,每条语句的后面都需要以一个分号(;)结尾。为了养成严谨的编程风格,建议大家编写脚本时,语句后一定要加上分号(;),这也有助于我们形成一种良好的编程习惯。

  WML Script语句的书写和排列格式比较自由。我们可以在同一程序行中连续写上多个语句,也可以把同一语句分成多行排列。WML Script将根据分号(;)来确定语句的具体内容。

  WML Script的语句主要包括两类。第一类是基本语句,如空语句、表达式语句、块语句、变量语句和return语句等;第二类是条件语句,如if语句;第三类是循环语句,如while语句、for语句、break语句和continue语句等。下面我们分别讲解这些语句的语法、功能和使用方法。

  5.1.1 基本语句

  WML Script基本语句主要用于程序格式控制和变量声明,其中有些语句我们已经不太陌生了。

  空语句

  空语句用于定义一个空的程序行,它没有任何标识符和操作符,也不执行任何操作。它只是以分号(;)结束。其语法格式为:

  ;

  显然,空语句是一种十分特殊的语句。由是我们为了让程序具有更好的可读性,通常在程序中的适当地方加上几个空语句,以起到分隔或突出的作用。例如,下面的几行程序中就含有一个空语句:

  str="Hello";

  val=25;

  ;

  MyVal=val*val+5;

  alert("Hi,Hi!!!");

  再如,while语句用于判断一个条件并在条件满足的时候执行相应的任务,但如果希望条件满足的时候什么也不作,那么就可以给它配上一个空语句,使之条件满足的执行空操作:

  while(!poll(device));

  这实际上是while语句和空语句组成的两条语句。其中的分号(;)在这里就代表了空语句。这两条语句的作用是在poll()函数为真()之前一直等待。

  表达式语句

  表达式语句用于向变量赋值,或进行数学计算,或进行函数调用。表达式语句也是我们最常用的一种语句,语法格式为:

  表达式;

  下面几行程序都是合法的表达式语句:

  str="Hey"+yourName;

  val3=prevVal+4

  counter++;

  myValue1=counter,myValue2=val3

  alert("Watch out!");

  retVal=16*Lang.max(val3,counter);

  块语句

  块语句使用两个花括号({ })包含一个语句集,形成一个语句体。WML Script的许多语句都需要使用块语句来实现语句体,快语句的语法格式为:

  {

  语句列表;

  }

  下面的简单程序就是使用块语句的例子:

  }

  vari=0;

  var x=Lang.abs(b);

  popUp("Remember!");

  }

  变量语句

  变量语句用于生命变量并可进行变量的初始化赋值。如果用户不赋值,那么WML Script会自动将变量语句生命的变量赋予一个空字符串("")。基本的语法格式为:

  var 变量名;

  如果像一次生命多个变量,则相邻变量名之间使用逗号(,)间隔,其语法格式为:

  VAR 变量名1,变量名2......,变量名n;

  如果想在生命变量时同时初始化变量,则可按如下语法格式书写:

  var 变量名=初始化

  为便于大家更好的掌握变量语句,我们给出一个多出使用该语句的程序:

  function count(stu){

  var result=0; //声明变量的同时初始化变量

  while(str!=""){

  var ind=0; //每次循环都初始化一次

  // 为退出循环,本块语句内应当提供修改变量str值的语句

  };

  return result

  };

  function example(param){

  var a=0;

  if(param>a){

  var b=a+1; //声明b变量的同时使用a变量初始化b变量

  }else{

  var b=a+2; //声明c变量的同时使用a变量初始化c变量

  };

  return a; //返回a变量的值

  };

  注释语句

  严格来讲,注释语句在WML Script中还不算是真正的语句,它只是一种前指向的规定。不过它也有严格的语法和标注方法,所以我们这里还是像其他编程语言处理的一样,把WML Script注释方法以语句的形式介绍一下。

  注释在程序执行的时候没有任何作用,但是可以用于对程序进行解释,则增强程序的可读性。为了形成良好的编程风格,我们应该养成书写注释的良好习惯,注释有两种表达方式:

  (1)通过双斜线注释一行,这样在双斜先后的字符将成为注释而不被执行。该注释行可以单独一行书写,也可以放在其他语句的后面。

  例如,可以进行如下所示的注释:

  //变量j用于小数每月的天数

  j=0; //我们这里将j赋值为0

  (2)通过符号“/*”和“*/”来规定注释语句,这种注释方式可以进行多行注释,符号“/*”和“*/”之间的内容就是注释语句。例如,可以进行如下所示的多行注释:

  /*我们定义了两个变量:i和j。其中:

  i用于描述每年中的月数,

  而j用于描述每月的天数*/

  j=0; /*我们这里将j赋值为0*/

  return语句

  return语句主要用在函数体中,在函数结束前,可以通过return语句,把函数处理的结果返回给调用函数的语句。它的语法格式如下:

  return表达式;

  下面的函数给出了应用return语句的例子:

  function square(x){

  if(!(Lang.isFloat(x)))return invalid;

  return x*x

  };

  5.1.2 条件语句

  在条件语句中,当满足某种条件时 ,就会执行指定的一些代码,而在代码组另外某种条件时,则会执行另外一些代码。WML Script的条件语句就是if...else语句,它的一般表达相识如下:

  if(条件){

  代码块1

  }

  else{

  代码块2

  }

  这样,当条件满足时,就执行代码块1;如果条件不满足则执行代码块2。代码块和代码块2中如果只有一个条语句,那么,花括号({ })就可以省略;而如果有多条语句,则必须实用花括号将代码块包括在其中。在if...else语句种,其中的else部分是可选的,也就是说,我们可以使用如下的表达形式:

  if(条件){

  代码块

  }

  这样,当条件满足时,就执行代码块,如果条件不满足则什么也不做。

  例如,如果我们需要对一个学生的成绩进行判定,如果大于等于60分,那么我们就认为该学生成绩合格了,反之则认为不合格,同时一并将状态记录到变量status种,相应的WMLScript语句如下所示:

  if(score>=60) status="pass";

  else status="fail";

  再如,我们可以通过对天气是否阳光普照(sunShines)的情况进行判断,来给变量myDay赋值,并累计好天气(goodDays)的天数。程序如下:

  if(sunShines) {

  myDay="Good";

  goodDays++;

  }else

  myDays="Oh well...";

  5.1.3 循环语句

  使用循环语句可以反复执行某个代码块,直到循环结束条件满足后才停止执行。WML Script中有两种循环语句:for语句和while语句,同时还有两终于循环密切相关的操作语言:break语句和continue语句。

  for语句

  for语句可以创建一个带条件的循环,它还有3个可选的条件表达式,用于控制循环。这3个条件表达式放在一个括号里,并以分号(;)间隔。for语句的一般语法形式如下:

  for(初始表达式;循环条件;递增表达式){

  代码块

  }

  for语句的执行主要包括以下几个步骤:

  (1)执行初始表达式。在一般情况下,初始表达式完成的功能是在循环中对循环计数器赋初值。所以在这种意义上,初始表达式也可以采用“var 变量声明列表;”的形式来定义。

  (2)判断循环条件。如果循环条件为真(ture),则执行循环体中的语句,即至步骤(3);否则,循环条件为假(false)或者invalid,就结束循环;

  (3)执行循环代码。然后,在执行递增表达式。一般情况下,我们在递增表达式中对循环计数器进行处理,最后在返回步骤2执行。

  例如,下面的for语句建立了一个循环。初始表达式为定义变量index并付初值0,循环条件为index<100,递增表达式为每循环一次index增加1。当index增加到100时候,循环结束。程序如下:

  for(var index=0;index<100;index++){

  count+=index;

  myFunc(count);

  };

  while 语句

  while语句也可常见一个循环,它的一般语法表达式如下:

  while(循环条件){

  代码块

  }

  while语句的执行过程包括以下几个步骤:

  (1)判断循环条件是否为真。如果循环条件为真,则执行循环;如果为假或为invalid,则跳出循环。

  (2)执行循环中的代码块,然后返回步骤(1)

  下面的程序就是使用while语句的简单例子:

  var counter=0

  var total=0

  while(counter<3){

  counter++;

  total+=c;

  };

  其中建立的循环仅当变量counter的值小于3时执行,否则就结束循环。

  显然,如果循环条件不能为假或为invalid,那么while循环就会无休止的反复执行下去。因此,我们在代码块中一定要有能够改变循环条件的变量,否则,就很有可能会陷入死循环而不能终止程序,下面就是一个死循环的例子:

  var x=1;

  var y=0;

  while(x<=1){

  y=x+1;

  }

  这个程序中,因为变量x的值在循环中不能发生变化,所以循环条件在判断的时候永远为真,所以成为了死循环。因此,对于while语句我们往往使用如下所示的语法形式:

  初始表达式

  while(循环条件){

  代码块

  递增表达式

  }

  这种情况下,while语句的功能和for语句的功能就一样了,不过用while语句编写的程序可读性更强一些。所以我们也可以采用while语句来完成index增加到100的循环。

  程序如下:

  var index=0

  while (index<100){

  counter+=index;

  myFunc(count);

  index++;

  };

  break语句

  为了更好的解决死循环问题,WML Script项大多数编成语言一样提供了break语句。break语句可以使程序执行跳出循环。不论是for语句还是while语句,只要在循环中使用了break语句,那么程序执行到break语句后就立即跳出当前循环,然后继续执行下去。

  break语句的予发行时如下:

  break;

  例如,在下面的函数中我们使用了break语句,它是当index=3时跳出循环。如果不是用该语句,函数中的while循环直到index=6时才可以结束。程序如下:

  funcition testBreak(x){

  var index=0;

  while(index<6){

  if(index==3)break;

  index++

  };

  retrun index*x;

  ;

  continue语句

  continue语句的功能和break语句的功能看起来有些类似,但实际上却不一样。循环执行时遇到break语句通常是跳出当前循环,但循环执行到continue语句并不跳出当前循环,而是不执行循环中在continue语句后面的代码块,直接结束循环的本轮运行,然后马上开始下一轮循环的运行。

  在while语句的循环中,遇到continue语句后,程序会直接判断循环条件从而开始下一轮循环。在for语句的循环中,遇到continue语句后程序会直接执行递增表达式,然后判断循环条件从而开始下一轮循环。

  例如,我们想利用for循环求1到10之间偶数的和,其WML Script语句如下:

  var sum=0;

  for (var j=1;j<=10;j++){

  if(j%2!=0)

  continue;

  sun+j;

  };

  在这个例子中,在j%2!=0的情况下,也就是j为奇数的情况下,程序执行continue语句,这时,并没有如同break语句一样跳出循环的运行,而是不执行循环中后面的语句而直接执行递增表达式开始下一轮循环的执行,这样,就可以不将其数j的之类即如总和中。

  再如,我们想利用while循环求0到4之间出3以外几个数的和,则可以使用continue语句进行控制。程序如下;

  var index=0;

  var count=0;

  while (index<5){

  index++;

  if(index==3)

  continue;

  cont+=index;

  };

  这以程序中,当index等于3时,“index==3”为真,所以执行continue语句,不再把此时index的值加大count中,而是开始下一轮的循环。

  break语句

  为了更好的解决死循环问题,WML Script项大多数编成语言一样提供了break语句。break语句可以使程序执行跳出循环。不论是for语句还是while语句,只要在循环中使用了break语句,那么程序执行到break语句后就立即跳出当前循环,然后继续执行下去。

  break语句的予发行时如下:

  break;

  例如,在下面的函数中我们使用了break语句,它是当index=3时跳出循环。如果不是用该语句,函数中的while循环直到index=6时才可以结束。程序如下:

  funcition testBreak(x){

  var index=0;

  while(index<6){

  if(index==3)break;

  index++

  };

  retrun index*x;

  ;

  continue语句

  continue语句的功能和break语句的功能看起来有些类似,但实际上却不一样。循环执行时遇到break语句通常是跳出当前循环,但循环执行到continue语句并不跳出当前循环,而是不执行循环中在continue语句后面的代码块,直接结束循环的本轮运行,然后马上开始下一轮循环的运行。

  在while语句的循环中,遇到continue语句后,程序会直接判断循环条件从而开始下一轮循环。在for语句的循环中,遇到continue语句后程序会直接执行递增表达式,然后判断循环条件从而开始下一轮循环。

  例如,我们想利用for循环求1到10之间偶数的和,其WML Script语句如下:

  var sum=0;

  for (var j=1;j<=10;j++){

  if(j%2!=0)

  continue;

  sun+j;

  };

  在这个例子中,在j%2!=0的情况下,也就是j为奇数的情况下,程序执行continue语句,这时,并没有如同break语句一样跳出循环的运行,而是不执行循环中后面的语句而直接执行递增表达式开始下一轮循环的执行,这样,就可以不将其数j的之类即如总和中。

  再如,我们想利用while循环求0到4之间出3以外几个数的和,则可以使用continue语句进行控制。程序如下;

  var index=0;

  var count=0;

  while (index<5){

  index++;

  if(index==3)

  continue;

  cont+=index;

  };

  这以程序中,当index等于3时,“index==3”为真,所以执行continue语句,不再把此时index的值加大count中,而是开始下一轮的循环。

  5.2.2 函数的调用

  编写好的函数必须经过合法的调用,才可以发挥它应用的作用。函数调用将返回一个值,比如一个计算结果。WML Script中的函数主要可以分为内部函数、外部函数和库函数,下面我们就介绍这3类函数的调用方法。

  内部函数

  所谓内部函数是指函数的定义与其调用函数在同一个脚本文件内的函数,对内部函数的调用称为内部调用。内部函数的调用非常简单,只需提供函数名和所需参数值即可,参数值必须和函数定义时指定的参数个数即类型一致。而且函数调用需要使用操作符来接收或处理被调用的返回值。

  内部函数可以在其定义之前调用,也可以在其定义之后调用。例如,下面就是一个在函数定义之后调用的例子。

  function test1(val){

  return val*val;

  };

  function test2(param){

  return test1(param+1);

  };

  这个例子中定义了两个函数test1和test2。test1函数用于计算给定参数值的平方并将结果返回;test2函数将给定的参数值加1,然后这个和为参数值,来调用test1函数,得到结果后在将给结果返回到调用test2函数的语句。

  注意,本例中test2函数调用了test1函数,这种在函数中调用其他函数的方法称为函数调用嵌套。WML Script的内部函数、外部函数和库函数都支持嵌套调用,后面我们专门介绍这方面的内容。

  外部函数

  外部函数使一个在WML Scrupt外部文件中定义的函数。调用外部函数的方法与调用内部函数的方法基本类似,不同之处在于调用处外部函数时一是要指定外部文件的地址即名称,二是要在调用的外部函数名的前面加上外部文件的名称。

  WML Script规则使用use url来指定外部文件,语法格式为:

  use url还有外部函数的外部文件名 外部文件所在的URL;

  这样,WML Script的预编译头就可以将外部文件映射为一个可以在内部使用的标识。然后,使用这个标识并加上井号键(#)和标准的函数调用即可实现外部函数调用,语法格式为:

  外部文件名#外部函数(参数列表);

  例如,http://www.host.com/script下有我们需要的外部文件,名为OtherScript,所以我们可使用use url来指定该文件:

  use url OtherScript"http://www.host.com/script"

  这一外部文件中含有我们需要调用的外部函数testme,则可采用“外部文件名#外部函数(参数列表)”的形式来调用它:

  OtherScript#testme(param+1);

  这个例子完整的写出来,就是下面的程序:

  use url OtherScript"http://www.host.com/script"

  function test(param){

  return OtherScript#testme(param+1);

  };

  库函数

  特别指定,WML Script的库函数一律是指它的标准库函数。因为与标准库函数对应,WML Script还有一些非标准的库函数。我们这里先介绍标准库函数,非标准库函数后面再介绍。

  所有库函数都有所数的库,函数的库中通常含有一类函数。因此,调用某个库函数时,一要指定它的库名,二要指定它的函数名。WML Script规定,调用标准库函数时可以通过在函数库的名字后面加上句点号(.)和库函数的标准调用来实现,语法格式为:

  函数库名.函数名(参数列表);

  例如,WML Script的浮点库即Float库中有一个开根方的函数sqrt,该函数只有一个参数,那么调用squrt库函数的方法为:

  Float.sqrt(number);//这里要求number大于或等于0

  下面给出了调用库函数的简单例子。首先一param参数值调用Lang.abs()函数,返回结果加1后再作为参数调用Float.sqrt()函数,它的返回结果作为内部函数test的返回值:

  function test(param){

  return Float.sqrt(Lang.abs(param)+1);

  };

  2.3 函数的嵌套调用

  WML Script的函数定义都是互相平行、独立的,定义函数的时候我们不能在一个函数内定义另外一个函数,也就是说,函数定义是不能嵌套的。但是,函数调用确是可以嵌套的,也就是说,我们可以在调用一个函数的过程中调用另外一个函数。

  它的执行过程是:

  (1)执行a函数开头部分;

  (2)遇到调用b函数的操作语句,流程则专区执行b函数;

  (3)执行b函数开头部分;

  (4)遇到调用c函数的操作语句,流程则专区执行c函数;

  (5)执行b函数,如果没有其他嵌套的函数,则完成c函数的全部操作;

  (6)返回调用c函数的语句,即返回到b函数;

  (7)继续执行b函数中尚未执行的操作,直到b函数结束;

  (8)返回a函数中调用b函数的语句;

  (9)继续执行a函数的剩余操作,直到函数结束。

  function myFunC(param1){

  return param1*param1=Float.squt(Lang.abs(param)+1);

  };

  function myFunB(param0){

  return myFunC(param0+1)*|param0+12;

  };

  function myFunA(param){

  return myFunB(param*param+1);

  };

  5.3 预编译

  WML Script的预编译主要用于在编译阶段控制编译器的行为。与编译头一般在文件开头和函数声明之前指定,WML Script规定所有的预编译头都是一关键词use加上指定的预编译属性进行指定。

  在大多数的编程中,我们比较长用的预编译行为主要涉及外部文件声明、访问权和Meta信息设置。

  5.3.1 外部文件

  我们知道,使用URL地址可以定位一个WML Script文件。利用该URL地址;在WML Script编程中我们可以通过预编译来调用WML Script的外部文件,外部文件预编译头的声明方法是use url,其语法格式如下:

  use url外部文件名 "URL"地址

  这样,我们在当前文件的编程中就可以使用该预编译头声明的外部文件,从而可以调用该外部文件的函数。其语法格式为:

  外部文件名#函数名(参数列表);

  例如,我们希望在当前的WML Script程序中调用OtherScript外部文件中的check()函数,而且我们知道OtherScript文件的URL地址为http://www.host.com/app/script。因此,我们可以使用use url来声明这一外部文件:

  use url OtherScript"http://www.host.com/script"

  随后,我们就可以在程序中调用OtherScript中的check()函数了:

  function test(par1,par2)

  {

  return OtherScript#check(par1,parr2);

  };

  其中调用执行的过程如下:

  (1)找到WML Script外部文件的URL地址;

  (2)当前函数从指定的URL地址值装载外部文件;

  (3)检测外部文件的内容,并执行其中的check()函数。

  ure url 预编译头指定的外部文件名在当前程序中必须唯一,用户不能指定不同URL地址的同名外部文件,否则在调用外部文件时就会发生混乱。

  另外,use url预编译头中的URL地址也可以是相对URL地址。相对URL的起始位置是当前程序文件所在的位置,并在此基础上根据URL进行定位。

  如果URL地址中的字符包含有转义字符,则WML Script将根据转义要求进行转义。不过,程序在编译的时候编译器并不会对他们进行转义,而是在程序执行时完成,检查URL格式和URL地址的有效性。

  5.3 预编译

  WML Script的预编译主要用于在编译阶段控制编译器的行为。与编译头一般在文件开头和函数声明之前指定,WML Script规定所有的预编译头都是一关键词use加上指定的预编译属性进行指定。

  在大多数的编程中,我们比较长用的预编译行为主要涉及外部文件声明、访问权和Meta信息设置。

  5.3.1 外部文件

  我们知道,使用URL地址可以定位一个WML Script文件。利用该URL地址;在WML Script编程中我们可以通过预编译来调用WML Script的外部文件,外部文件预编译头的声明方法是use url,其语法格式如下:

  use url外部文件名 "URL"地址

  这样,我们在当前文件的编程中就可以使用该预编译头声明的外部文件,从而可以调用该外部文件的函数。其语法格式为:

  外部文件名#函数名(参数列表);

  例如,我们希望在当前的WML Script程序中调用OtherScript外部文件中的check()函数,而且我们知道OtherScript文件的URL地址为http://www.host.com/app/script。因此,我们可以使用use url来声明这一外部文件:

  use url OtherScript"http://www.host.com/script"

  随后,我们就可以在程序中调用OtherScript中的check()函数了:

  function test(par1,par2)

  {

  return OtherScript#check(par1,parr2);

  };

  其中调用执行的过程如下:

  (1)找到WML Script外部文件的URL地址;

  (2)当前函数从指定的URL地址值装载外部文件;

  (3)检测外部文件的内容,并执行其中的check()函数。

  ure url 预编译头指定的外部文件名在当前程序中必须唯一,用户不能指定不同URL地址的同名外部文件,否则在调用外部文件时就会发生混乱。

  另外,use url预编译头中的URL地址也可以是相对URL地址。相对URL的起始位置是当前程序文件所在的位置,并在此基础上根据URL进行定位。

  如果URL地址中的字符包含有转义字符,则WML Script将根据转义要求进行转义。不过,程序在编译的时候编译器并不会对他们进行转义,而是在程序执行时完成,检查URL格式和URL地址的有效性。