JavaScript+jQuery网页特效设计任务驱动教程
上QQ阅读APP看书,第一时间看更新

任务2-2 采用多种方式显示当前的日期

在网页中以自定义形式显示当前日期及星期数,日期格式为:年-月-日-星期。以自定义形式显示当前日期及星期数的JavaScript程序之一如表2-2所示。

表2-2 以自定义形式显示当前日期及星期数的JavaScript程序之一

表2-2中的代码解释如下。

(1)03行为声明变量的语句,声明了4个变量,变量名分别为year、month、day和tempdate。

(2)04行创建一个日期对象示例,其内容为当前日期和时间,且将日期对象示例赋给变量tempdate。

(3)05行使用日期对象的getFullYear()方法获取日期对象的当前年份数,且赋给变量year。

(4)06行使用日期对象的getMonth方法获取日期对象的当前月份数,且赋给变量month。注意由于月份的返回值是从0开始的索引序号,即1月返回0,其他月份以此类推,为了正确表述月份,需要做加1处理,让1月显示为“1月”而不是“0月”。

(5)07行使用日期对象的getDate方法获取日期对象的当前日期数(即1~31),且赋给变量day。

(6)08行使用文档对象document的write方法向网页中输出当前日期,表达式“year+"年"+month+"月"+day+"日"+"    "”使用运算符“+”连接字符串,其中year、month、day是变量,"年"、"月"、"日"和"    "是字符串。

(7)09行使用关键字new和构造函数Array()创建一个数组对象weekarray,并且创建数组对象时指定了数组的长度为7,即该数组元素的个数为7,数组元素的下标(序列号)从0开始,各个数组元素的下标为0~6。此时数组对象的每一个元素都尚未指定类型。

(8)10~16行分别给数组对象weekarray的各个元素赋值。

(9)17行使用日期对象的getDay方法获取日期对象的当前星期数,其返回值为0~6,序号0对应星期日,序号1对应星期一,以此类推,序号6对应星期六。

(10)使用“[]”运算符访问数组元素,即获取当前星期数的中文表示。

以自定义形式显示当前日期及星期数的JavaScript程序之二如表2-3所示。

表2-3 以自定义形式显示当前日期及星期数的JavaScript程序之二

表2-3中的代码解释如下。

(1)08行使用条件运算符保证年份用4位数表示。

(2)09行通过网页元素的innerHTML属性显示当前日期和时间。使用字符串的charAt()显示星期数。

以自定义形式显示当前日期及星期数的JavaScript程序之三如表2-4所示。

表2-4 以自定义形式显示当前日期及星期数的JavaScript程序之三

表2-4中的代码解释如下。

(1)07~09行分别使用两种不同的方式定义数组。

(2)10行中通过访问数组元素的方式isMonth[today.getMonth()]获取当前的月份名称。

(3)11行中通过访问数组元素的方式isDay[today.getDay()]获取当前的星期名称。

知识必备

2.1 JavaScript的运算符与表达式

运算符也称为操作符,JavaScript常用的运算符有:算术运算符(包括+、-、*、/、%、++、--)、比较运算符(包括<、<=、>、>=、==、!=)、逻辑运算符(&&、||、!)、赋值运算符(=)、条件运算符(?:)以及其他类型的运算符。

表达式是运算符和操作数的组合,表达式通过求值确定表达式的值,这个值是操作数据实施运算所确定的结果。由于表达式是以运算符为基础的,所以表达式可以分为算术表达式、字符串表达式、赋值表达式、逻辑表达式等。

1.JavaScript的算术运算符

算术运算符用于执行变量或数值之间的算术运算。给定y=5,表2-5解释了这些算术运算符。

表2-5 JavaScript的算术运算符及示例

2.JavaScript的赋值运算符

赋值运算符用于给JavaScript变量赋值。给定x=10和y=5,表2-6解释了这些赋值运算符。

表2-6 JavaScript的赋值运算符及示例

3.JavaScript的连接运算符

+运算符用于把文本值或字符串变量连接起来。如果需要把两个或多个字符串变量连接起来,则使用+运算符。

例如:

txt1="What a very "; 
txt2="nice day"; 
txt3=txt1+txt2; 

在以上语句执行后,变量txt3包含的值是"What a very nice day"。

注意 要想在两个字符串之间增加空格,需要把空格插入一个字符串之中。

例如:

txt1="What a very "; 

或者把空格插入表达式中。

例如:

txt3=txt1+" "+txt2; 

在以上语句执行后,变量txt3包含的值均为

"What a very nice day" 

对字符串和数字进行加法运算,其运算规则是:如果把数字与字符串相加,结果将成为字符串。

例如:

x=5+"5" ; 
document.write(x); 

运算结果为:55

例如:

x="5"+5 ; 
document.write(x); 

运算结果为:55

4.JavaScript的比较运算符

比较运算符确定变量或它们的值之间的关系。在逻辑语句中使用比较运算符,通过比较变量或它们的值来计算出表达式的值是为true还是为false。

给定x=5,表2-7解释了比较运算符。

表2-7 JavaScript的比较运算符及示例

可以在条件语句中使用比较运算符对值进行比较,然后根据结果执行不同的语句。例如:

if(hour<12)document.write("上午好!");

注意 当JavaScript两个不同类型的值进行比较时,首先会将其弱化成相同的类型。因为苹果不能和梨做比较,所以false、undefined、null、0、""、NaN都弱化成false。这种强制转化并不是一直存在的,只有当作为表达式使用的时候才存在。

例如:

var someVar =0 ; 
alert(someVar == false) ;      //显示 true 

5.JavaScript的逻辑运算符

逻辑运算符用于测定变量或值之间的逻辑关系,其值为true或false。

给定x=6及y=3,表2-8解释了逻辑运算符。

表2-8 JavaScript的逻辑运算符及示例

6.JavaScript的条件运算符

JavaScript还包含了基于某些条件对变量进行赋值的条件运算符。语法格式如下。

variablename=(condition)?value1:value2

例如:

tax=(salary>1500)?1:0;

如果变量salary中的值大于1500,则向变量tax赋值1,否则赋值0。

条件运算符(?:)是一个三元运算符,它由2个符号和3个运算数组成,两个符号分别位于3个运算数之间。第1个运算数是布尔型,通常由一个表达式计算而来,第2个运算数和第3个运算数可以是任意类型的数据,或者是任何形式的表达式。条件运算符的运算规则是:如果第1个运算数为true,那么条件表达式的值就是第2个运算数的值;如果第1个运算数是false,那么条件表达式的值就是第3个运算数的值。

对于条件表达式“typeof(x)=='string'?eval(x):x”,如果typeof(x)的返回值是string,则条件表达式的值就是eval(x),即当x是字符串时,当作表达式进行处理,即条件表达式的值为表达式的计算结果;否则直接将变量x的值作为条件表达式的值。

2.2 JavaScript的语句及其规则

JavaScript语句向浏览器发出命令,告诉浏览器该做什么。

1.分号

分号用于分隔JavaScript语句,通常在每条可执行的语句结尾添加分号。使用分号的另一用处是在一行中编写多条语句。最好的代码编写习惯是统一加入分号,因为没有分号,有些浏览器就不能正确运行。

提示 在JavaScript中,每行结尾的分号是可选的。ECMAScript则允许开发者自行决定是否以分号结束一行代码。如果没有分号,ECMAScript就把折行代码的结尾看作该语句的结尾(与Visual Basic和VBScript相似),但其前提是没有破坏代码的语义。

根据ECMAScript标准,下面两行代码都是正确的。

var test1 = "red" 
var test2 = "blue" ; 

2.JavaScript代码

JavaScript代码是JavaScript语句的序列,浏览器会按照编写顺序来执行每条语句。

3.JavaScript代码块

JavaScript语句通过代码块的形式进行组合,代码块由左花括号“{”开始,由右花括号“}”结束,程序语句被封装在左括号和右括号之间。

代码块的作用是使语句序列按其顺序执行,JavaScript函数是将语句组合在块中的典型示例。

4.JavaScript区分大小写

JavaScript对大小写敏感,变量、函数名、运算符以及其他一切对象都是区分大小写的。变量test与变量TEST是不同的,同样,函数getElementById与getElementbyID也是不同的。

5.空格

JavaScript会忽略多余的空格,可以向脚本添加空格来提高其可读性。

下面的两行代码是等效的。

var name="李明"; 
var name = "李明" ; 

6.对代码行进行折行

可以在文本字符串中使用反斜杠\对代码行进行换行。以下代码会正确显示。

document.write("Hello \ 
World!"); 

但以下的折行则是不允许的。

document.write \ 
("Hello World!"); 

提示 JavaScript是脚本语言,浏览器会在读取代码时逐行地执行脚本代码。但传统编程语言会在执行前对所有代码进行编译。

2.3 JavaScript的条件语句

JavaScript的条件语句用于基于不同的条件来执行不同的语句。编写程序代码时,经常需要为不同的决定执行不同的动作,可以在代码中使用条件语句来完成该任务。

在JavaScript中,可以使用以下条件语句。

(1)if语句:只有当指定条件为true时,才使用该语句来执行代码。

(2)if…else…语句:当条件为true时执行代码,当条件为false时执行其他代码。

(3)if…else if…else…语句:使用该语句来选择多个代码块之一来执行。

(4)switch语句:使用该语句来选择多个代码块之一来执行。

1.if语句

只有当指定条件为true时,该语句才会执行代码。语法格式:

if (条件) 
   { 
       // 当条件为 true 时执行的代码 
   } 

注意 应使用小写的if。使用大写字母(IF)会产生JavaScript错误。

例如:

当时间小于20:00时,问候语显示为“Good day”。

if (time
    { 
       x="Good day"; 
    } 

该语句不包含else,只有在指定条件为true时才执行代码。

2.if…else…语句

使用if…else…语句在条件为true时执行代码,在条件为false时执行其他代码。语法格式:

if (条件) 
    { 
        // 当条件为 true 时执行的代码 
    } 
else 
    { 
        // 当条件为 false 时执行的代码 
    } 

例如:

当时间小于20:00时,显示问候语"Good day",否则显示问候语"Good evening"。

if (time<20) 
    { 
         x="Good day"; 
     } 
else 
     { 
         x="Good evening"; 
     }

3.if…else if…else…语句

使用if…else if…else…语句来选择多个代码块之一来执行。

语法格式:

if (条件 1) 
    { 
       // 当条件 1 为 true 时执行的代码 
    } 
else if (条件 2) 
    { 
       // 当条件 2 为 true 时执行的代码 
    } 
else 
    { 
       // 当条件 1 和条件 2 都不为 true 时执行的代码 
    }

例如:

时间小于10:00时,显示问候语Good morning,时间小于20:00时,显示问候语Good day,否则显示问候语Good evening。

if (time<10) 
 { 
 x="Good morning"; 
 } 
else if (time<20) 
    { 
       x="Good day"; 
     } 
else 
     { 
       x="Good evening"; 
     }

4.switch语句

使用switch语句来选择要执行的多个代码块之一。

语法格式:

switch(n) 
{ 
    case 1: 
         // 执行代码块 1 
         break; 
    case 2: 
         // 执行代码块 2 
         break; 
    default: 
         // n 与 case 1 和 case 2 不同时执行的代码 
}

首先设置表达式n(通常是一个变量),随后表达式的值会与结构中每个case的值进行比较。如果存在匹配项,则与该case关联的代码块会被执行。使用break来阻止代码自动向下一个case运行,跳出switch语句。

switch语句中的表达式不一定是条件表达式,可以是普通的表达式,其值可以是数值、字符串或布尔值。执行switch语句时,首先将表达式的值与一组数据进行比较,当表达式的值与所列数据值相等时,执行其中的语句块;如果表达式的值与所有列出的数据值都不相等,就会执行default后的语句块;如果没有default关键字,就会跳出switch语句执行switch语句后面的语句。

例如:

显示今日的周名称。注意Sunday=0、Monday=1、Tuesday=2等。

var day=new Date().getDay(); 
switch (day) 
{ 
case 0: 
      x="Today it's Sunday"; 
      break; 
case 1: 
      x="Today it's Monday"; 
      break; 
case 2: 
      x="Today it's Tuesday"; 
      break; 
case 3: 
      x="Today it's Wednesday"; 
      break; 
case 4: 
      x="Today it's Thursday"; 
      break; 
case 5: 
      x="Today it's Friday"; 
      break; 
case 6: 
      x="Today it's Saturday"; 
      break; 
}

5.default关键词

使用default关键词来指定匹配不存在时执行的操作。

例如:

如果今天不是周六或周日,则会输出默认的消息。

var day=new Date().getDay(); 
switch (day) 
{ 
case 6: 
     x="Today it's Saturday"; 
     break; 
case 0: 
     x="Today it's Sunday"; 
     break; 
default: 
     x="Looking forward to the Weekend"; 
}

2.4 JavaScript的函数

函数是由事件驱动的,或者当它被调用时执行可重复使用的代码块。函数是功能相对独立的代码块,该代码块中的语句被作为一个整体来执行。

函数是那些只能由事件或是函数调用来执行的脚本的容器,因此,在浏览器最初加载和执行包含在网页中的脚本时,函数并没有被执行。函数的目的是包含那些要完成某个任务的脚本,这样就能够随时执行该脚本和运行该任务。

例如:

<script> 
     function openWin( ) 
     { 
         alert("感谢你光临本网站"); 
     } 
</script> 
<button onclick="openWin ( )">单击这里</button>

1.JavaScript函数的语法格式

函数就是包含在花括号中的代码块,前面使用了关键词function,其语法格式如下。

function functionName() 
   { 
      // 这里是要执行的代码 
   }

当调用该函数时,会执行函数内的代码。

可以在某事件发生时直接调用函数(如用户单击按钮时),并且可由JavaScript在任何位置进行调用。

提示 JavaScript对大小写敏感。关键字function必须是小写的,并且必须以与函数名称相同的大小写来调用函数。

2.调用带参数的函数

函数能够通过函数的参数来接收数据,函数可以有一个或多个形式参数,函数调用基于函数的形式参数可以有一个或多个实际参数。形式参数(形参,parameter)和实际参数(实参,argument)常会被弄混,形参是函数定义的组成部分,而实参则是在调用函数时用到的表达式。

在调用带参数的函数时,可以向其传递值,这些值被称为参数值。这些参数值可以在函数内使用。可以传送任意多个参数,由逗号“,”分隔,其形式如下。

functionName(argument1 , argument2) 

声明函数时,将参数作为变量来声明。

例如:

function functionName( var1 , var2 ) 
   { 
        // 这里是要执行的代码 
   } 

变量和参数必须以一致的顺序出现,第一个变量就是第一个被传递的参数的给定值,以此类推。包含1个参数的函数示例如下所示。

<script> 
     function openWin(msg) 
      { 
         alert(msg) ; 
      } 
</script> 
<button onclick="openWin('感谢你光临本网站')" >单击这里</button>

包含2个参数的函数示例如下所示。

<script> 
function displayInfo(name , job) 
    { 
       alert("欢迎" + name + job); 
     } 
</script> 
<button onclick=" displayInfo( '张三' , '工程师' )">单击这里</button>

上面的函数会在按钮被单击时出现提示信息:"欢迎张三工程师"。

可以使用不同的参数来调用该函数,出现不同的提示信息。

例如:

<button onclick=" displayInfo('李四' , '教授')">单击这里</button> 
<button onclick=" displayInfo('王五' , '会计师')">单击这里</button>

根据单击的按钮不同,会出现不同的提示信息:"欢迎李四教授"或"欢迎王五会计师"。

3.调用有返回值的函数

有时,我们希望函数将值返回调用它的地方,使用return语句就可以实现。在使用return语句时,函数会停止执行,并返回指定的值。

语法格式:

function myFunction() 
    { 
      var x=5; 
      return x; 
    }

上面的函数会返回5。

提示 整个JavaScript并不会停止执行,只是函数执行结束。JavaScript将继续执行调用语句后面的代码。

函数调用将被返回值取代:var myVar=myFunction();

myVar变量的值是5,也就是函数“myFunction()”所返回的值。

即使不把它保存为变量,也可以使用返回值。

例如:

document.getElementById("demo").innerHTML=myFunction();

网页中“demo”元素的内容将是5,也就是函数“myFunction()”所返回的值。可以使返回值基于传递到函数中的参数。

例如:计算两个数字的乘积,并返回结果。

function myFunction(a,b) 
    { 
        return a*b ; 
    } 
document.getElementById("demo").innerHTML=myFunction(4,3) ; 

网页中“demo”元素的内容将是12。

如果只是希望退出函数,也可以使用return语句,返回值是可选的。

4.JavaScript的全局函数

JavaScript有以下7个全局函数,用于完成一些常用的功能:eval()、parseInt()、parseFloat()、isNaN()、isFinite()、escape()、unescape()。

(1)eval()。

该函数用于计算某个字符串,并执行其中的JavaScript代码。语法格式为:eval(str),对表达式str进行运算,返回表达式str的运算结果,其中参数str可以是任何有效的表达式。例如,eval(document.body.clientWidth-90)。

(2)parseInt()。

该函数将字符串的首位字符转化为整型数字,如果字符串不是以数字开头,那么将返回NaN。例如,表达式parseInt("2abc")返回数字2,表达式parseInt("abc")返回NaN。

语法格式为:parseInt(string,radix),参数radix可以是2~36的任意整数,当radix为0或10时,提取的整数以10为基数表示,即返回10、20、30、…、100、110、120…该函数也可以用于将字符串转换为整数。

(3)parseFloat()。

该函数将字符串的首位字符转化为浮点型数字,如果字符串不是以数字开头,那么将返回NaN。例如,表达式parseFloat("2.6abc")返回数字2.6,表达式parseFloat("abc")返回NaN。

(4)isNaN()。

该函数主要用于检验某个值是否为NaN。例如,表达式isNaN("NaN")的值为true,表达式isNaN(123)的值为false。

(5)isFinite()。

该函数用于检查其参数是否是无穷大。语法格式为:isFinite(number)。

如果number是有限数字(或可转换为有限数字),那么返回true。如果number是NaN(非数字),或者是正、负无穷大的数,则返回false。例如,表达式isFinite(123)的值为true,表达式isFinite("NaN")的值为false。

(6)escape()。

该函数用于对字符串进行编码,这样就可以在所有的计算机上读取该字符串。语法格式为:escape(str),其返回值为已编码的string的副本。其中某些字符被替换成了十六进制的转义序列。例如,表达式escape("a(b)|d")的值为a%28b%29%7Cd。

(7)unescape()。

该函数可对通过escape()编码的字符串进行解码。语法格式为:unescape(str),其返回值为string被解码后的一个副本。该函数的工作原理是:通过找到形式为%xx和%uxxxx的字符序列(x表示十六进制的数字),用Unicode字符\u00xx和\uxxxx替换这样的字符序列进行解码。

例如,表达式unescape(escape("a(b)|d"))的值为a(b)|d。

注意 ECMAScript v3已从标准中删除了escape()和unescape()函数,并反对使用它,因此应该用decodeURI()和decodeURIComponent()取而代之。

2.5 JavaScript的String(字符串)对象

JavaScript的字符串对象是存储字符(如"Good")的变量。

字符串可以是引号中的任意文本,可以使用单引号或双引号,也可以在字符串中使用引号,只要不匹配包围字符串的引号即可。

例如:

var answer="Nice to meet you!" ; 
var answer="He is called 'Bill'" ; 
var answer='He is called "Bill"' ; 

String对象的属性、方法及示例如表2-9所示。

表2-9 String对象的属性与方法

注意 String对象的substring()和substr()的区别。

String对象的substring()方法的一般形式为substring(indexStart,indexEnd),即从字符串中截取子串,两个参数分别是截取子串的起始和终止字符的索引值,截取的子串不包含索引值较大的参数对应的字符。若忽略indexEnd,则字符串的末尾是终止值。若indexStart=indexEnd,则返回空字符串。

String对象的substr()方法的一般形式为substr(start,length),即从start索引开始,向后截取length个字符。若省略length,则一直截取到字符串尾;若length设定的个数超过了字符串的结尾,则返回到字符串结尾的子字符串。

2.6 JavaScript的Math(数学)对象

Math对象包含用于各种数学运算的属性和方法,Math对象的内置方法可以在不使用构造函数创建对象时直接调用。调用形式为Math.数学函数(参数)。

例如,计算cos(π/6)可以写成:Math.cos(Math.PI/6)。

1.数学值

JavaScript提供了8种可被Math对象访问的数学值。

(1)常数:Math.E。

(2)圆周率:Math.PI。

(3)2的平方根:Math.SQRT2。

(4)1/2的平方根:Math.SQRT1_2。

(5)2的自然对数:Math.LN2。

(6)10的自然对数:Math.LN10。

(7)以2为底的e的对数:Math.LOG2E。

(8)以10为底的e的对数:Math.LOG10E。

2.数学方法

除了可以被Math对象访问的数学值以外,还有几个函数(方法)可以使用,如表2-10所示。

表2-10 Math对象的函数(方法)

2.7 JavaScript的Date(日期)对象

日期对象主要用于从系统中获得当前的日期和时间,设置当前日期和时间,在时间、日期同字符串之间转换。

1.定义日期

Date对象用于处理日期和时间。可以通过new关键词来定义Date对象。

以下代码定义了名称为d的Date对象:var d=new Date()。

提示 Date对象自动使用当前的日期和时间作为其初始值。

2.操作日期

通过使用针对日期对象的方法,可以很容易地对日期进行操作。例如:为日期对象设置一个特定的日期(2020年10月1日)。

var d=new Date() ; 
d.setFullYear(2020 , 9 , 1) ; 
document.write(d) ; 

注意 表示月份的参数为0~11。也就是说,如果希望把月设置为10月,则参数应该是9。

下面的示例代码将日期对象设置为5天后的日期。

var d=new Date() ; 
d.setDate(d.getDate()+5) ; 
document.write(d) ; 

注意 如果增加天数会改变月份或者年份,那么日期对象会自动完成这种转换。

3.比较日期

日期对象也可用于比较两个日期。

例如:将当前日期与2020年10月1日进行比较。

var d=new Date(); 
d.setFullYear(2020 , 10 , 1); 
var today = new Date(); 
if (d>today) 
     { 
         alert("今天在 2020 年 10 月 1 日之前") ; 
    }

4.Date对象的函数

Date对象的函数(方法)及示例如表2-11所示。

表2-11 Date对象的函数(方法)

2.8 JavaScript的计时方法

通过使用JavaScript的计时方法,可以在一个设定的时间间隔之后执行代码,而不是在函数被调用后立即执行。我们称之为计时事件。

JavaScritp中使用计时事件的两个关键方法是setTimeout()和clearTimeout()。

1.setTimeout()方法

setTimeout()用于指定未来的某个时间执行代码,即经过指定时间间隔后调用函数或运算表达式。

语法格式:

var t=setTimeout("javascript 语句" , 毫秒数) ; 

setTimeout()方法会返回某个值。在上面的语句中,值被储存在名为t的变量中。如果希望取消这个setTimeout(),就可以使用这个变量名来指定它。

setTimeout()的第1个参数是含有JavaScript语句的字符串。这个语句可能诸如"alert('5 seconds!')",或者对函数进行调用,诸如alertMsg()"。

第2个参数指示从当前起多少毫秒后执行第1个参数。

提示 1000毫秒等于1秒。

2.clearTimeout()方法

clearTimeout()用于取消setTimeout()。

例如:在网页上显示一个钟表。

<script> 
function startTime() 
{ 
    var today=new Date() ; 
    var h=today.getHours() ; 
    var m=today.getMinutes() ; 
    var s=today.getSeconds() ; 
    m=checkTime(m) ; 
    s=checkTime(s) ; 
    document.getElementById('txtTime').innerHTML=h+":"+m+":"+s ;
   t=setTimeout('startTime()' , 500) ; 
} 
function checkTime(i) 
{ 
    if (i<10){ 
       i="0" + i ; 
     } 
    return i ; 
} 
</script> 
<button onclick="startTime()">单击这里</button> 
<div id="txtTime"></div>

3.setInterval()方法

setInterval()方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval()方法会不停地调用函数,直到clearInterval()被调用或窗口被关闭。由setInterval()返回的值可用作clearInterval()方法的参数。

语法格式:

setInterval(code , millisec) 

两个参数都是必需参数,其中参数code表示要调用的函数或要执行的代码串,millisec表示周期性执行或调用code之间的时间间隔,以毫秒计。

4.clearInterval()方法

clearInterval()方法可取消由setInterval()设置的毫秒时间。

语法格式:

clearInterval(id_of_setinterval) 

参数id_of_setinterval必须是由setInterval()返回的ID值。

2.9 JavaScript的RegExp对象及其方法

RegExp对象表示正则表达式,它是对字符串执行模式匹配的强大工具。当检索某个文本时,可以使用一种模式来描述要检索的内容,RegExp就是这种模式。简单的模式可以是一个单独的字符,更复杂的模式包括了更多的字符,并可用于解析、格式检查、替换等。RegExp对象可以规定字符串中的检索位置,以及要检索的字符类型等。

1.创建RegExp对象

(1)直接量语法。

正则表达式的直接量语法格式如下。

/pattern/attributes 

(2)创建RegExp对象的语法。

创建RegExp对象的语法格式如下。

new RegExp(pattern , attributes) ; 

(3)RegExp对象的参数说明。

参数pattern表示一个字符串,指定了正则表达式的模式或其他正则表达式。

参数attributes表示一个可选的字符串,包含属性“g”“i”和“m”,分别用于指定全局匹配、不区分大小写的匹配和多行匹配。ECMAScript标准化之前,不支持m属性。如果pattern是正则表达式,而不是字符串,则必须省略该参数。

(4)RegExp对象的返回值。

一个新的RegExp对象具有指定的模式和标志。如果参数pattern是正则表达式而不是字符串,那么RegExp()构造函数将用与指定的RegExp相同的模式和标志创建一个新的RegExp对象。

如果不使用new运算符,而将RegExp()作为函数调用,那么它的行为与用new运算符调用时一样,只是当pattern是正则表达式时,它只返回pattern,而不再创建一个新的RegExp对象。

(5)创建RegExp对象时抛出的异常。

①SyntaxError:如果pattern不是合法的正则表达式,或attributes含有“g”“i”和“m”之外的字符,创建RegExp对象时会抛出该异常。

②TypeError:如果pattern是RegExp对象,但没有省略attributes参数,就抛出该异常。

2.创建RegExp对象的修饰符

创建RegExp对象的修饰符如表2-12所示。

表2-12 创建RegExp对象的修饰符

(1)g修饰符。

g修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。所有主流浏览器都支持g修饰符。

例如,对字符串中的“is”进行全局搜索。

var str="Is this all there is?" ; 
var patt1=/is/g ; 
document.write(str.match(patt1)); 

由于字符串str中第1个“Is”首字母为大写,所以搜索结果中不包含第1个“Is”,只包括其后的2个“is”。

(2)i修饰符。

i修饰符用于执行对大小写不敏感的匹配。所有主流浏览器都支持i修饰符。

例如,对字符串中的“is”进行全局且不区分大小写的搜索。

var str="Is this all there is? "; 
var patt1=/is/gi ; 
document.write(str.match(patt1)); 

搜索结果中包含全部的3个“is”。

3.正则表达式的模式符

(1)带方括号的模式表达式。

方括号用于查找某个范围内的字符。带方括号的模式表达式如表2-13所示。

表2-13 带方括号的模式表达式

(2)模式表达式中的元字符。

元字符(Metacharacter)是拥有特殊含义的字符,模式表达式中的元字符如表2-14所示。

表2-14 模式表达式中的元字符

(3)模式表达式中的量词。

模式表达式中的量词如表2-15所示。

表2-15 模式表达式中的量词

4.RegExp对象的属性

RegExp对象的属性如表2-16所示。

表2-16 RegExp对象的属性

5.RegExp对象的方法

RegExp对象有3种方法:test()、exec()和compile()。

(1)test()方法。

test()方法用于检测一个字符串是否匹配某个模式,或者检索字符串中的指定值,返回值是true或false。

例如:

<script type="text/javascript"> 
    var patt1=new RegExp("r"); 
    document.write(patt1.test("javascript")) ; 
</script>

由于该字符串中存在字母“r”,以上代码的输出将是:true。

(2)exec()方法。

exec()方法用于检索字符串中的正则表达式的匹配,或者检索字符串中的指定值,返回值是被找到的值。如果没有发现匹配,则返回null。

语法格式:

RegExpObject.exec(str) 

其中参数str为必需参数,表示要检查的字符串。

exec()方法的功能非常强大,它是一个通用的方法,而且使用起来也比test()方法以及支持正则表达式的String对象的方法更为复杂。

如果exec()找到了匹配的文本,则返回一个结果数组。否则,返回null。此数组的第0个元素是与正则表达式相匹配的文本,第1个元素是与RegExpObject的第1个子表达式相匹配的文本(如果有的话),第2个元素是与RegExpObject的第2个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和length属性之外,exec()方法还返回两个属性。index属性声明匹配文本的第1个字符的位置,input属性则存放被检索的字符串string。可以看得出,在调用非全局的RegExp对象的exec()方法时,返回的数组与调用方法String.match()返回的数组是相同的。

但是,当RegExpObject是一个全局正则表达式时,exec()的行为就稍微复杂一些。它会在RegExpObject的lastIndex属性指定的字符处开始检索字符串string。当exec()找到了与表达式相匹配的文本时,在匹配后,它将把RegExpObject的lastIndex属性设置为匹配文本的最后一个字符的下一个位置。也就是说,可以通过反复调用exec()方法来遍历字符串中的所有匹配文本。当exec()再也找不到匹配的文本时,它将返回null,并把lastIndex属性重置为0。

如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动把lastIndex属性重置为0。

无论RegExpObject是否是全局模式,exec()都会把完整的细节添加到它返回的数组中。这就是exec()与String.match()的不同之处,后者在全局模式下返回的信息要少得多。因此可以这么说,在循环中反复调用exec()方法是唯一一种获得全局模式的完整模式匹配信息的方法。

例如:全局检索字符串中的字母a。

<script type="text/javascript"> 
     var str = "javascript"; 
     var patt = new RegExp("a","g"); 
     var result; 
     while ((result = patt.exec(str)) != null) { 
         document.write(result+" | "); 
         document.write(result.lastIndex+" | "); 
     } 
</script>

输出结果为a|2|a|4|

(3)compile()方法。

compile()方法用于改变RegExp,或者在脚本执行过程中编译正则表达式,也可以用于改变和重新编译正则表达式。既可以改变检索模式,也可以添加或删除第2个参数。

语法格式:

RegExpObject.compile(regexp , modifier) 

其中参数regexp表示正则表达式,参数modifier用于规定匹配的类型。“g”用于全局匹配,“i”用于不区分大小写,“gi”用于全局不区分大小写的匹配。

例如:在字符串中全局搜索“to”,并用“for”替换,然后使用compile()方法改变正则表达式,用“he”替换“me”。

<script type="text/javascript"> 
    var str="good luck to me,good luck to you"; 
    patt=/to/g; 
    str2=str.replace(patt,"for"); 
    document.write(str2+"<br />"); 
    patt=/me/; 
    patt.compile(patt); 
    str2=str.replace(patt,"he"); 
    document.write(str2); 
</script>

输出结果为

good luck for me,good luck for you 
good luck to he,good luck to you 

2.10 支持正则表达式的String对象的方法

1.search()方法

search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。

语法格式:

stringObject.search(regexp) 

其中参数regexp可以是需要在stringObject中检索的子串,也可以是需要检索的RegExp对象。如果要执行忽略大小写的检索,则追加标志i。

其返回值是stringObject中第一个与regexp相匹配的子串的起始位置。如果没有找到任何匹配的子串,则返回-1。

search()方法不执行全局匹配,它将同时忽略标志g和regexp的lastIndex属性,并且总是从字符串的开始进行检索,这意味着它总是返回stringObject的第一个匹配的位置。

例如:分别检索“a”“R”。

<script type="text/javascript"> 
    var str="javascript" ; 
    document.write(str.search(/a/)) ; 
    document.write(" | ") ; 
    document.write(str.search(/R/)) ; //区分大小写 
    document.write(" | ") ;
    document.write(str.search(/R/i)) //不区分大小写 
</script>

输出结果为

1|-1|6

2.match()方法

可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似于indexOf()和lastIndexOf(),但是它返回指定的值,而不是字符串的位置。

语法格式如下。

(1)stringObject.match(searchvalue)。

其中参数searchvalue指定要检索的字符串值。

(2)stringObject.match(regexp)。

其中参数regexp规定要匹配的模式的RegExp对象。如果该参数不是RegExp对象,则需要首先把它传递给RegExp构造函数,将其转换为RegExp对象。

其返回值为存放匹配结果的数组,该数组的内容依赖于regexp是否具有全局标志g。

match()方法将检索字符串stringObject,以找到一个或多个与regexp匹配的文本。这个方法的行为在很大程度上依赖于regexp是否具有标志g。如果regexp没有标志g,那么match()方法就只能在stringObject中执行一次匹配。如果没有找到任何匹配的文本,match()将返回null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第0个元素存放的是匹配文本,而其余元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性,index属性声明匹配文本的起始字符在stringObject中的位置,input属性声明对stringObject的引用。如果regexp具有标志g,则match()方法将执行全局检索,找到stringObject中的所有匹配子字符串。若没有找到任何匹配的子串,则返回null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是stringObject中的所有匹配子串,而且也没有index属性或input属性。

注意 在全局检索模式下,match()不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果需要这些全局检索的信息,可以使用RegExp.exec()方法。

例如:使用全局匹配的正则表达式来检索字符串中的所有数字。

<script type="text/javascript"> 
    var str="39 plus 2 equal 41" 
    document.write(str.match(/\d+/g)) 
</script>

输出结果为:39,2,41

3.replace()方法

replace()方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

语法格式如下。

stringObject.replace(regexp/substr , replacement) 

其中参数regexp/substr指定子字符串或要替换的模式的RegExp对象,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为RegExp对象。参数replacement为一个字符串值,指定了替换文本或生成替换文本的函数。

返回值为一个新的字符串,是用replacement替换了regexp的第一次匹配或所有匹配之后得到的。

字符串stringObject的replace()方法执行查找并替换的操作。它将在stringObject中查找与regexp相匹配的子字符串,然后用replacement来替换这些子串。如果regexp具有全局标志g,那么replace()方法将替换所有匹配的子串;否则,它只替换第一个匹配子串。

replacement可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。但是replacement中的$字符具有特定的含义。表2-17说明从模式匹配得到的字符串将用于替换。

表2-17 参数replacement中的$字符的含义

注意 ECMAScript v3规定,replace()方法的参数replacement可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有0个或多个这样的参数。接下来的参数是一个整数,声明了匹配在stringObject中出现的位置。最后一个参数是stringObject本身。

示例1:确保匹配字符串大写字符的正确性。

<script type="text/javascript"> 
    text = "javascript"; 
    document.write(text.replace(/javascript/i, "JavaScript")); 
</script>

输出结果为JavaScript。

示例2:将所有的双引号替换为单引号。

<script type="text/javascript"> 
     name = '"a", "b"'; 
     document.write(name.replace(/"([^"]*)"/g, "'$1'")); 
</script>

输出结果为'a','b'。

示例3:将字符串中所有单词的首字母都转换为大写。

name = 'aaa bbb ccc'; 
uw=name.replace(/\b\w+\b/g , function(word){ 
       return word.substring(0,1).toUpperCase()+word.substring(1);} 
); 
document.write(uw)

输出结果为Aaa Bbb Ccc。

4.split()方法

用于把一个字符串分割成字符串数组。语法格式如下。

stringObject.split(separator,howmany) 

其中参数separator是必需参数,该参数为字符串或正则表达式,从该参数指定的位置分割stringObject。参数howmany是可选参数,该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组;如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

返回值为一个字符串数组。该数组是通过在separator指定的边界处将字符串stringObject分割成子串创建的。返回的数组中的字符串不包括separator自身。如果separator是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)。

如果把空字符串("")用作separator,那么stringObject中的每个字符之间都会被分割。String.split()执行的操作与Array.join执行的操作相反。

例如:按照不同的方式来分割字符串。

<script type="text/javascript"> 
    var str="How are you?" 
    document.write(str.split("") + "<br />")   //把句子分割成单词 
    document.write(str.split("") + "<br />")   //把单词分割为字母 
    document.write(str.split(" ",2))           //返回一部分字符,这里只返回前两个单词 
</script>

输出结果为

How,are,you? 
H,o,w, ,a,r,e, ,y,o,u,? 
How,are 

下列表达式将分割结构为更复杂的字符串:

"2:3:4:5".split(":")     //将返回["2", "3", "4", "5"] 
"|a|b|c".split("|")      //将返回["", "a", "b", "c"] 

可以把句子分割成单词。

var words = sentence.split(' ') 

或者使用正则表达式作为separator。

var words = sentence.split(/\s+/) 

2.11 JavaScript和jQuery的使用比较

网页中有以下HTML代码:<div id="demo"></div>,分别使用JavaScript方式和jQuery方式实现在该标签位置输出文本信息。

(1)使用JavaScript方式实现。

JavaScript允许通过id查找HTML元素,然后改变HTML元素的内容。

function displayInfo( ) 
  { 
    var obj=document.getElementById("demo") ; 
    obj.innerHTML="JavaScript" ; 
  } 
displayInfo() ;

(2)使用jQuery方式实现。

jQuery允许通过CSS选择器来选取元素,然后设置HTML元素的内容。

function displayInfo() 
   { 
     $("#demo").html("jQuery") ; 
   }

jQuery的主要函数是$()函数(jQuery函数)。如果向该函数传递DOM对象,它会返回jQuery对象,带有向其添加的jQuery功能。jQuery使用$("#id")代替document.getElementById("id"),即通过id获取元素。使用$("tagName")代替document.getElementByTagName("tagName"),即通过标签名称获取HTML元素。

上面代码的最后一行,DOM文档对象$(document)被传递到jQuery。当向jQuery传递DOM对象时,jQuery会返回jQuery对象。

ready()是jQuery对象的一个方法,由于在JavaScript中函数就是对象,因此可以把displayInfo作为变量传递给jQuery的ready方法。

提示 jQuery返回jQuery对象,与已传递的DOM对象不同。jQuery对象拥有的属性和方法与DOM对象的不同。不能在jQuery对象上使用DOM的属性和方法。

引导训练