《JavaScript和jQuery实战手册(原书第2版)》——3.1节使程序智能地响应-阿里云开发者社区

开发者社区> 华章出版社> 正文

《JavaScript和jQuery实战手册(原书第2版)》——3.1节使程序智能地响应

简介: 本节书摘来自华章社区《JavaScript和jQuery实战手册(原书第2版)》一书中的第3章,第3.1节使程序智能地响应,作者:David Sawyer McFarland,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.1 使程序智能地响应
我们的生活充满了选择:“我今天穿什么”、“午餐吃什么”、“星期五晚上该干什么”等。我们所做的很多选择取决于某个条件。例如,假设确定想要在星期五晚上看电影,我们可能会问自己一堆问题,例如,“有什么好的电影上映吗” 、“电影能够准时开演吗” 、“我带了足够的钱去电影院吗”(买一袋爆米花要17块钱)。
假设有一场电影刚好在我们去的时候上映。我们就会问自己一个简单的问题“我身上的钱够吗”。如果回答是够,我们就向电影院出发。如果回答是不够,我们就不去。但是在另一个星期五,我们可能有足够的钱,那就去电影院。对于条件是如何影响我们做出决定,电影院只是一个简单的例子。
JavaScript具有同样的判断功能,叫做条件语句。基本上,条件语句就是一个简单的是或非的问题。如果回答是,程序就会做一件事情;如果回答否,它就做其他的事情。条件语句是最重要的编程概念之一:它允许程序对不同的情况做出反应并智能地操作。我们将会在编程中无数次地用到它们,而这里只是给出如何使用它们的几个例子,以使你对其用法有一个清晰了解。
表单验证。当想要确定某个人填写了一个表单中所有必需的字段(“Name,”、“Address,”、“E-mail,”等)的时候,我们将使用条件语句。例如,如果Name字段为空,就不提交该表单。
拖拽。如果添加了在Web页面中拖动元素的功能,可能要检查访问者把元素放在页面的什么位置。例如,如果拖动一幅图片到一个垃圾箱图像上,我们就要让照片在页面上消失。
评估输入。如果弹出一个窗口来询问访问者类似这样的问题:“您愿意回答几个针对这个Web站点的评价的问题吗?”我们可能希望脚本能够根据访问者如何回答这个问题而做出不同的反应。
图3-1给出了使用条件语句的应用程序的一个例子。


1f4603bdc786c00bc91320ec8a02993d81bfec79

3.1.1 条件语句基础
条件语句也叫做“if/then”语句,因为只有在问题的答案为真的时候,它们才执行一项任务:“如果我有足够的钱,就去看电影。”条件语句的基本结构如下所示:

if ( condition ) {
    // some action happens here
}

这条语句有三个部分:if表示接下来的程序是一个条件语句;圆括号包括了答案为是或否的问题,叫做条件(稍后会更详细地介绍它);花括号({ })表示如果条件为真所应该执行的JavaScript代码的开始和结束。
注意: 在上面列出的代码中,“// some action happens here”是一条JavaScript注释。它不是实际运行的代码,只是在程序中保留的一个提示;并且,在这个例子中它指出,你作为代码的阅读者应该期待代码的这部分是什么内容。参见2.11节对于注释的更多介绍。
在很多情况下,条件是两个值之间的比较。例如,假设创建了一个游戏,当分数超过100的时候,玩家胜出。在这个程序中,我们需要通过一个变量来记录玩家的分数,并且,在某个时刻,我们需要检查这个分数是否超过100分。JavaScript检查玩家是否胜出的代码如下所示:

if (score > 100) {
 alert('You won!');
}

重要的部分是score > 100。这条语句是一个条件,并且,它直接测试存储在score变量中的值是否大于100。如果是,那么就会显示一个“You won!”的对话框;如果玩家的分数小于或等于100,那么JavaScript解释器就跳过警告框并直接到程序的下一部分。图3-2给出了这一过程的一个图示。


4be254ce9bc0b24ce4bf9777b6f2d0777fedcf0f

除了>(大于),还有其他几种操作符用来比较数值(参见表3-1)。
提示: 在包含在一对花括号中的JavaScript代码的每一行前面输入两个空格。空格(或制表符)缩进了这些行,使得人们更容易看到开始和结束的花括号,并且很容易看清楚哪些代码属于条件语句。常用两个空格,但是,如果4个空格使得你的代码更容易阅读,那就用4个空格。本书中的例子总是缩进花括号中的代码。


9fdc5f82ebe20a96c6035d53672878fa69999dcb

更为常见的是,我们将测试两个值是否相等。例如,假设我们创建了一个基于JavaScript的测验,并且其中的一个问题是“土星有多少颗卫星?”人们的答案将存储在一个名为answer的变量中。可以编写如下所示的一条条件语句:

if (answer == 31) {
 alert('Correct. Saturn has 31 moons.');
}
这里的一对等号(==)并不是输入错误,它们让JavaScript解释器比较两个值并且判断二者是否相等。别忘了,在JavaScript中,单个等号是赋值操作符,通过它可以把一个值存储到变量中:
var score = 0; //stores 0 into the variable score
由于JavaScript解释器已经给单个等号赋予了特殊的含义,当要比较两个值来判断它们是否相等的时候,我们需要使用两个等号符号。
我们也可以使用==(叫做相等性操作符)来查看两个字符串是否相同。例如,假设我们想让用户在表单中输入一个表示颜色的单词,并且如果他们输入“red”,就把页面的背景颜色改为红色。为此我们使用条件操作符:
if (enteredColor == 'red') {
 document.body.style.backgroundColor='red';
}
注意:    在上面的代码中,现在先不要关心如何改变页面颜色。我们将在本书4.8.2节学习如何使用JavaScript来动态控制CSS属性。
也可以使用不相等操作符来测试两个值是否不同:
if (answer != 31) {
 alert("Wrong! That's not how many moons Saturn has.");
}
惊叹号翻译为“不”,因此,!=意味着“不相等”。在这个例子中,如果存储在answer中的值不是31,那么可怜的测验参与者将看到一条错误警告消息。
条件为真才运行的代码,并不像前面的例子那样仅限于单行代码。只要愿意,可以在开始花括号和结束花括号之间使用多行JavaScript代码。例如,作为JavaScript测验示例的一部分,我们可以保持一个记分牌,记录测验参与者答对了多少道题。因此,当土星问题的回答正确,我们就给测验参与者的总分加1。可以通过如下的条件测试做到这点:
if (answer == 31) {
 alert('Correct. Saturn has 31 moons.');
 numCorrect += 1;
}

注意: 正如本书2.5.5节所介绍的,上面的代码行(numCorrect += 1)直接给变量numCorrect中当前的值加上1。
并且也可以在花括号之间添加额外的JavaScript代码行,可以添加条件为真时运行的任何代码。
高级用户提示
Boolean返回值
在本书2.3.3节,我们认识了布尔值:true和false。布尔乍一看好像不是非常有用,但是,当我们开始使用条件语句的时候,会发现它们是必需的。实际上,既然条件确实是一个非真即假的问题,那么这个问题的答案就是一个布尔值。例如,查看如下代码:

var x = 4;
if ( x == 4 ) {
    //do something
}

代码的第一行把数值4存储到变量x中。下一行中的条件是一个简单的问题:存储在x中的值是4吗?在这个例子中,它是,因此,花括号之间的JavaScript代码运行。但是,圆括号之间真正发生的事情是:JavaScript解释器把条件转换为一个布尔值,用编程的术语来说,解释器计算了条件。如果条件计算为真(意味着问题的答案是yes),那么,花括号之间的代码运行。然而,如果条件计算为false,那么,花括号之间的代码将会略过。
布尔的一种常见用法是创建一个所谓的标志,这是表示某件事是否为真的一个变量。例如,当验证填满了访问者提交的信息的一个页面的时候,我们可能首先创建一个带有布尔值为true的valid变量,这意味着,首先,假设访问者正确地填写了表单。然后,依次查看每个表单字段,如果任何字段遗漏了信息或者信息的类型不对,可以把valid的值改为false。在检查了所有的表单字段字后,测试valid中存储的内容,如果仍然是true,就提交表单。如果不是true(以为这一个或多个表单字段为空),则显示某些错误消息并防止表单提交:

var valid = true;
//  lot of other programming gunk happens in here
// if a field has a problem then you set 
valid to false
if (valid) {
 //submit form
} else {
 //print lots of error messages
}

3.1.2 添加备用计划
但是,如果条件为false呢?3.1.1节中的基本条件语句并没有准备一个备用计划,以便在条件为false的时候运行。在现实情况中,当我们要确定星期五晚上干什么并且没有足够的钱看电影的时候,我们还想要干些其他的事情。if语句有它自己的备用计划,叫做else子句。例如,以JavaScript测验脚本为例,我们想要通知测验参加者的回答是正确的或者是错误的。在这里,可以这么做:

if (answer == 31) {
 alert('Correct. Saturn has 31 moons.');
 numCorrect = numCorrect + 1;
} else {
 alert("Wrong! That's not how many moons Saturn has.");
}

这段代码创建了一种要么/要么的情景,两条消息中只有一条会显示(参见图3-3)。如果数值31存储在变量answer中,那么,“correct”警告窗口显示;否则,“wrong”警告窗口显示。
要创建一条else子句,只要在条件语句的结束花括号之后添加一个“else”,再跟上另外一对花括号即可。在花括号之间,添加如果条件结果为false应该执行的代码。同样,只要你愿意,可以有多行代码作为else子句的部分。


5ce710f3a113a7a3190fd99e19bec5c49cb289d5

3.1.3 测试多个条件
有时候,我们想要测试多个条件并且拥有几种可能的输出。考虑这样一个游戏,主持人对你说:“你想要1号门、2号门还是3号门背后的奖金?”你只能选择其中之一。在日常活动中,我们也经常面对像这样的多个条件选择。
例如,回到“我星期五晚上干什么”的问题。你可能根据自己有多少钱以及愿意花多少钱来增加娱乐项目。例如,你可以这样开始,“如果我有超过50块钱,我就到外面好好吃一顿并看场电影(并且买点爆米花)”。如果没有50块钱,你可能会尝试另一个测试“如果我有35块钱或更多,我就好好地吃一顿”。如果没有35块钱,你可能会说:“如果我有12块钱或者更多,我就去看场电影。”最后,如果没有12块钱,你可能会说:“那我就待在家里看电视。”多么美妙的一个星期五晚上啊。
JavaScript允许我们使用else if语句执行同样的层叠逻辑。它像这样工作:从一条if语句开始,其选项为1号;然后,添加1个或多个else if语句,来提供可以触发其他选项的其他问题;最后,使用else子句作为退路。下面是其在JavaScript中的基本结构:

if (condition) {
 // door #1
} else if (condition2) {
 // door #2
} else {
 // door #3
}

这个结构是我们创建一个JavaScript“星期五之夜计划”程序所需要的所有内容。它询问访问者有多少钱,然后确定他们应该在星期五做什么(听起来有些熟悉吧)。我们可以使用在本书2.7节的教程中所学习的prompt()命令来收集访问者的反馈,并且使用一系列的if/else if语句来确定他应该做什么:

var fridayCash = prompt('How much money can you spend?', '');
if (fridayCash >= 50) {
 alert('You should go out to a dinner and a movie.');
} else if (fridayCash >= 35) {
 alert('You should go out to a fine meal.');
} else if (fridayCash >= 12) {
 alert('You should go see a movie.');
} else {
 alert('Looks like you will be watching TV.');
}

下面是对这个程序分步骤的分析:第一行代码打开一个提示对话框,询问访问者可以花费多少钱。访问者输入的内容将存储在名为fridayCash的变量中。下一行代码是一个测试:访问者输入的值是否大于或等于50?如果答案是肯定的,那么出现一个警告框,告诉他去吃顿饭并看场电影。此时,整个条件语句就完成了。JavaScript解释器略过下一条else if语句,接下来的else if语句,以及最后的else子句。使用条件语句,只会发生一种结果,因此,一旦JavaScript解释器遇到计算为true的一个条件,那么它为该条件运行花括号之间的JavaScript代码,并且略过条件语句中的其他所有内容(参见图3-4)。
假设访问者输入的是25。在这个例子中,第一个条件将不为true,因为25是一个小于50的数值。因此,JavaScript解释器跳过了针对第一个条件的花括号中的代码,并且继续 “25是否大于等于35”的else if 语句。既然答案为false,它跳过和这个条件相关的代码,并且遇到下一个else if语句。此时,条件询问“25是否大于等于12”,答案是true,因此,出现一个带有“You should go see a movie”消息的警告框并且程序结束,略过最终的else子句。
提示:还有另一种方式可以创建都测试同一个变量的一系列的条件语句,就像是在fridayCash示例中那样。switch语句可以做同样的事情,将在14.6.3节学习它。


ac7b37463587f0cc1744ab2f736f58c0ccc9d641

3.1.4 更复杂的条件
当处理多个不同的变量时,经常需要更加复杂的条件语句。例如,当验证表单中一个必需的E-mail地址字段的时候,我们想要确保字段不为空并且字段包含一个E-mail地址(而不只是随机输入的字母)。幸运的是,JavaScript允许做这类检查。
多个条件为真时
我们通常需要根据多个因素的组合来做出决定。例如,如果有足够的钱,可能想去看电影,并且也有想看的电影正在放映。在这种情况下,只有两个条件都为true时,才会去看电影。在JavaScript中,可以使用逻辑AND操作符来组合条件,可以用两个&符号(&&)表示。通过AND操作符可以把两个条件组合为一个条件语句。例如,如果想要查看一个数值是否在1~10之间,可以这么做:

if (a < 10 && a > 1) {
 //the value in a is between 1 and 10
 alert("The value " + a + " is between 1 and 10");
}

这个例子中有两个条件:第一个条件a < 10询问存储在变量a中的值是否小于10;第二个条件a > 1等同于“这个值是否大于1”。只有在两个条件都为true的时候,包含在花括号之间的JavaScript代码才会运行。因此,如果变量a中存储了数值0,第一个条件(a < 10)为true(0小于10),但是,第二个条件为false(0不大于1)。
不仅限于使用两个条件。只要需要,可以使用&&操作符连接尽可能多的条件:

if (b>0 && a>0 && c>0) {
 // all three variables are greater than 0
}

这段代码检查3个变量以确保这3个变量的值都大于0。如果有一个变量拥有值0或者更小的值,那么将不会执行花括号中的代码。
至少一个条件为true时
还有些时候,我们也要检查一系列的条件,但是只需要一个为true。例如,假设添加了一个键盘控制,以便访问者可以在一个照片库中从一幅图片跳转到另一幅图片。当访问者按下N键的时候,显示下一张照片。在这种情况下,当他按下n(小写)的时候,或者已经按下Caps Lock键的时候,即N(大写),都希望跳转到下一幅照片。我们需要一种或者/或者的逻辑:或者这个键按下,或者那个键按下。逻辑OR操作符有了用武之地,它用两个管道符号(||)表示:

if (key == 'n' || key == 'N') {
 //move to the next photo
}

提示: 按下Shift-可以输入一个管道符号。斜杠和管道符号共用的输入键通常在回车键的上方。
使用OR操作符,只要一个条件为真,就会运行花括号之间的JavaScript代码。
和AND操作符一样,我们可以比较两个以上的条件。例如,假设我们要创建一个JavaScript赛车游戏。玩家有时间的限定、有限的汽油量和有限的车辆数目(每次他撞毁或失去一辆车)。为了让游戏更有挑战性,当这三项都用完的时候,我们让游戏结束:

if (gas <= 0 || time <= 0 || cars <= 0) {
 //game is over
}
在测试多个条件的时候,有时候很难搞清楚条件语句的逻辑。一些程序员把每个条件组合到一对圆括号中,以使得逻辑更容易理解:
 if ((key == 'n') || (key == 'N')) {
 //move to the next photo
}

要阅读这段代码,只需要把每个组当成一个单独的测试。圆括号之间的操作的结果要么总是true,要么总是false。
对条件取反
如果你是超人迷,可能会知道Bizarro,这是超人的对头,居住在一个名叫Htrae(Earth的逆向拼写)的立方体卫星,其制服有一个反写的S,并且其通常的行为方式都是和超人相反的。当Bizarro说“是”的时候,他实际的意思是“不是”;而当他说“不是”的时候,他实际的意思是“是”。
JavaScript编程有一个类似的字符,叫做NOT操作符,它由一个惊叹号(!)表示。我们已经看到了NOT操作符和等号符号一起使用,表示“不等于”(!=)。但是,NOT操作符可以单独使用来表示把一个条件语句的结果取反;换句话说,它可以使得false意味着true,而使得true成为false。
当我们想要根据一个否定条件来运行某些代码的时候,就使用NOT操作符。例如,假设我们已经创建了一个名为valid的变量,其中包含了一个Boolean值,它要么为true要么为false(参见3.1节中的“高级用户提示:Boolean返回值”部分)。我们使用这个变量来记录访问者是否正确地填写了表单。当访问者试图提交表单的时候,JavaScript检查每个表单字段,确保它们满足了设置的要求(例如,字段不为空,并且其中必须有一个E-mail地址)。如果有问题,例如字段为空,可以把valid设置为false(valid = false)。
现在,如果想要做些事情,例如显示一个错误以阻止表单提交,可以编写如下所示的一个条件语句:

if (! valid) {
 //print errors and don't submit form
}

条件!valid可以翻译为“如果不是valid”,这意味着,如果valid为false,那么这个条件为true。若要搞清楚使用NOT操作符的一个条件的结果,只要计算没有NOT操作符的条件,然后对其取反即可。换句话说,如果条件结果为true,!操作符将其改为false,因此,条件语句不会运行。可以看到,NOT操作符很容易理解(用Bizarro的话来说:它很容易令人混淆,但是,如果你使用它的时间足够长,就会习惯)。

3.1.5 嵌套条件语句
大多数时候,计算机程序必须根据访问者提供的信息或者根据程序中的当前条件来做出判断。程序所做的判断越多,可能的结果也就越多,程序似乎也更“智能”。实际上,我们可能会发现在执行了一个条件语句之后,需要进一步做判断。
假设,在“星期五晚上干什么”的示例中,我们想要把程序扩展到包含一周的每个晚上。在这种情况下,我们需要首先确定是星期几,然后确定在这一天干什么。因此,可能有一个条件语句询问今天是否是星期五,如果是,有另外一系列的条件语句来确定这一天做什么:

if (dayOfWeek == 'Friday') {
 var fridayCash = prompt('How much money can you spend?', '');
 if (fridayCash >= 50) {
  alert('You should go out to a dinner and a movie.');
 } else if (fridayCash >= 35) {
  alert('You should go out to a fine meal.');
 } else if (fridayCash >= 12) {
  alert('You should go see a movie.');
 } else {
  alert('Looks like you will be watching TV.');
 }
}

在这个例子中,第一个条件询问存储在变量dayOfWeek中的值是否是字符串“Friday”。如果回答是yes,那么,显示提示对话框,从访问者那里获取某些信息,并且另一个条件语句开始运行。换句话说,第一个条件(dayOfWeek == 'Friday')是通向一组条件语句的条件。然而,如果dayOfWeek不是“Friday”,那么,条件为false并且嵌套的条件语句也会略过。

3.1.6 编写条件语句的技巧
3.1.5节中的嵌套条件语句的例子看上去可能有些令人惊讶。有这么多的()、{}、else和if。并且,如果你碰巧错误地输入了条件语句的一个关键部分,脚本就不会工作。在输入JavaScript的时候,还有几种方法便于更容易地使用条件语句。
提前输入两个花括号,然后再在其中输入代码。程序员常犯的一个错误就是忘了给条件语句添加一个表示结束的花括号。为了避免这个错误,先输入条件和花括号,然后再输入条件为true时执行的JavaScript代码。例如,像下面这样开始一个条件:

if (dayOfWeek=='Friday') {
    }
换句话说,输入if子句和第一个花括号,按下回车键两次,然后输入最后的结束花括号。现在,基本的语法是正确的,可以单击两个花括号之间的空白行并添加JavaScript代码。
在花括号中缩进代码。如果缩进了一对花括号之间的所有JavaScript代码,那会使得条件语句的结构更好看:
    if (a < 10 && a > 1) {
      alert("The value " + a + " is between 1 and 10");
    }
通过使用几个空格(或者按下Tab键),在花括号内缩进代码,这可以很容易地表示出哪些代码作为条件语句的一部分运行。如果有嵌套的条件语句,要在每个嵌套语句中缩进:
    if (a < 10 && a > 1) {
      //first level indenting for first conditional
      alert("The value " + a + " is between 1 and 10");
      if (a==5) {
        //second level indenting for 2nd conditional
        alert(a + " is half of ten.");
      }
    }
使用==比较相等性。当检查两个值是否相等的时候,不要忘了使用相等操作符,如下所示:
    if (name == 'Bob') {
常见的错误是使用一个等号,如下所示:
    if (name = 'Bob') {

单个等号会把值存储到变量中,因此,在这个例子中,字符串“Bob”将会存储到name变量中。JavaScript解释器会把这个步骤当做true,因此,条件后面的代码将总是会执行。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接