--- title: 在代码中做决定 - 条件语句 slug: learn/JavaScript/Building_blocks/conditionals translation_of: Learn/JavaScript/Building_blocks/conditionals ---
在任何的编程语言中,代码需要依靠不同的输入作出决定并且采取行动。例如,在游戏中,如果玩家的生命值变成了0,那么游戏就结束了。在天气应用中,如果在早晨运行,就显示一张日出的图片;如果在晚上,就显示星星和月亮的图片。在这篇文章中,我们将探索在JavaScript中所谓的条件语句是怎样工作的。
预备知识: | 基本的计算机知识,对HTML和CSS有基本的了解,JavaScript的第一步。 |
---|---|
目标: | 了解怎样在JavaScript中使用条件语句的结构。 |
人类(以及其他的动物)无时无刻不在做决定,这些决定都影响着他们的生活,从小事(“我应该吃一片还是两片饼干”)到重要的大事(“我应该留在我的祖国,在我父亲的农场工作;还是应该去美国学习天体物理学”)。
条件语句结构允许我们来描述在JavaScript中这样的选择,从不得不作出的选择(例如:“一片还是两片”)到产生的结果或这些选择(也许是“吃一片饼干”可能会“仍然感觉饿”,或者是“吃两片饼干”可能会“感觉饱了,但妈妈会因为我吃掉了所有的饼干而骂我”。)
让我们看看到目前为止你将会在JavaScript中用到的最常见的条件语句类型 — if ... else语句。
基本的if…else语法看起来像下面的 {{glossary("伪代码")}}:
if (condition) { code to run if condition is true } else { run some other code instead }
在这里我们有:
这段代码真的非常易懂——它说“如果(if)条件(condition)返回true,运行代码A,否则(else)运行代码B”
注意:你不一定需要else和第二个花括号——下面的代码也是符合语法规则的:
if (condition) { code to run if condition is true } run some other code
不过,这里你需要注意——在这种情况下,第二段代码不被条件语句控制,所以它总会运行,不管条件返回的是true还是false。这不一定是一件坏事,但这可能不是你想要的——你经常只想要运行一段代码或者另一段,而不是两个都运行。
最后,有时候你可能会看到 if…else 语句没有写花括号,像下面的速记风格:
if (condition) code to run if condition is true else run some other code instead
这是完全有效的代码,但不建议这样使用——因为如果有花括号进行代码切割的话,整体代码被切割为多行代码,更易读和易用。
为了更好的理解这种语法,让我们考虑一个真实的例子。想像一个孩子被他的父母要求帮助他们做家务。父母可能会说“嗨,宝贝儿,如果你帮我去购物,我会给你额外的零花钱,这样你就能买得起你想要的玩具了。”在JavaScript中,我们可以这样表示:
var shoppingDone = false; if (shoppingDone === true) { var childsAllowance = 10; } else { var childsAllowance = 5; }
这段代码显示的结果是变量 shoppingDone
总是返回 false
, 意味着对我们的穷孩子来说很失望。如果孩子去购物的话,就需要依靠我们提供机制来使父母把变量 shoppingDone
变成 true
。
Note: 你可以看到在Github上这个例子的完整版本(也可以在线运行)
最后一个例子提供给我们两个选择或结果,但是如果我们想要两个以上呢?
有一种方法来让你的 if…else
连接你的额外的选择和结果——使用else if
。每一个额外的选择要求放到 if() { ... }
和 else { ... }
里——看看下面更多涉及到的例子,它们属于一个普通的天气预报的应用的一部分。
<label for="weather">Select the weather type today: </label> <select id="weather"> <option value="">--Make a choice--</option> <option value="sunny">Sunny</option> <option value="rainy">Rainy</option> <option value="snowing">Snowing</option> <option value="overcast">Overcast</option> </select> <p></p>
var select = document.querySelector('select'); var para = document.querySelector('p'); select.addEventListener('change', setWeather); function setWeather() { var choice = select.value; if (choice === 'sunny') { para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.'; } else if (choice === 'rainy') { para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.'; } else if (choice === 'snowing') { para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.'; } else if (choice === 'overcast') { para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.'; } else { para.textContent = ''; } }
{{ EmbedLiveSample('else_if', '100%', 100) }}
<select>
添加了一个事件监听器,因此,当它的值改变时,setWeather()
函数被执行。choice
变量去存储当前被选的 <select>
中的值。接着我们用条件判断语句根据 choice
的值选择性的展示段落中的文本。注意 else if() {...}
段中的条件是怎么被判断的,除了第一个,它是在 if() {...}中被判断的。
else {...}
中的选择通常被叫做 “最后招数” — 在所有的条件都不为 true 时其中的代码会被执行。在这个例子中,如果用户没有选择任何一个选项,它会将段落中的文本清空,例如当用户决定重新选择最开始出现的"--Make a choice--"选项时,就会有这样的效果。Note: 你可以 在 GitHub 上找到这个例子 (也可以在线运行。)
比较运算符是用来判断条件语句中的条件的。我们先回过头来看看Basic math in JavaScript — numbers and operators 文章中的比较运算符。我们有如下选择:
===
和 !==
— 判断一个值是否严格等于,或不等于另一个。<
和 >
— 判断一个值是否小于,或大于另一个。<=
和 >=
— 判断一个值是否小于或等于,或者大于或等于另一个。Note: 如果你想复习这些内容,可以回顾之前链接上的材料。
我们想特别提到测试布尔值(true / false),和一个通用模式,你会频繁遇到它,任何不是 false
, undefined
, null
, 0
, NaN
的值,或一个空字符串('')在作为条件语句进行测试时实际返回true,因此您可以简单地使用变量名称来测试它是否为真,甚至是否存在(即它不是未定义的)。例如:
var cheese = 'Cheddar'; if (cheese) { console.log('Yay! Cheese available for making cheese on toast.'); } else { console.log('No cheese on toast for you today.'); }
而且,回到我们以前关于孩子为自己的父母做家务的例子,你可以这样写:
var shoppingDone = false; if (shoppingDone) { // don't need to explicitly specify '=== true' var childsAllowance = 10; } else { var childsAllowance = 5; }
将另一个if ... else 语句放在另一个中 - 嵌套它是完全可行的。例如,我们可以更新我们的天气预报应用程序,以显示更多的选择,具体取决于温度:
if (choice === 'sunny') { if (temperature < 86) { para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.'; } else if (temperature >= 86) { para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.'; } }
即使代码全部一起工作,每个if ... else语句完全独立于另一个。
如果要测试多个条件,而不需要编写嵌套if ... else语句,逻辑运算符可以帮助您。当在条件下使用时,前两个执行以下操作:
&&
— 逻辑与; 使得并列两个或者更多的表达式成为可能,只有当这些表达式每一个都返回true
时,整个表达式才会返回true.
||
— 逻辑或; 当两个或者更多表达式当中的任何一个返回 true
则整个表达式将会返回 true
.举一个逻辑 && 的例子, 刚才的那段代码片段可以写成下面这样:
if (choice === 'sunny' && temperature < 86) { para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.'; } else if (choice === 'sunny' && temperature >= 86) { para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.'; }
所以,只有当choice === 'sunny'
并且temperature < 86
都返回true
时,第一个代码块才能运行。
让我们快速看一个 || 的例子:
if (iceCreamVanOutside || houseStatus === 'on fire') { console.log('You should leave the house quickly.'); } else { console.log('Probably should just stay in then.'); }
最后一种类型的逻辑运算符, 逻辑非!
运算符表示, 可以用于对一个表达式取否. 让我们把 非运算符 结合上一个例子里的 或表达式 看看:
if (!(iceCreamVanOutside || houseStatus === 'on fire')) { console.log('Probably should just stay in then.'); } else { console.log('You should leave the house quickly.'); }
在这一段代码中,如果逻辑或所在的语句返回 true
,则非运算符会将其取否,于是整个表达式的返回值将会是false
。
您可以在任何结构中随意合并很多个逻辑表达式。接下来的例子将会只在或运算符两边的语句同时返回true时才会执行代码,这也就意味着整个与运算符语句将会返回true:
if ((x === 5 || y > 3 || z <= 10) && (loggedIn || userName === 'Steve')) { // run the code }
在条件语句中运用或逻辑运算符最常见的错误是尝试声明变量后,仅检查该变量一次的情况下赋予很多个都会返回true的值,不同的值之间用 ||
(或)运算符分隔。比如:
if (x === 5 || 7 || 10 || 20) { // run my code }
在这个例子里 if(...)
里的条件总为真,因为 7 (或者其它非零的数) 的值总是为真. 这个条件实际意思是 "如果x等于5, 或者7为真 — 它总是成立的". 这不是我们想要的逻辑,为了 让它正常工作你必须指定每个或表达式两边都是完整的检查:
if (x === 5 || x === 7 || x === 10 ||x === 20) { // run my code }
if...else
语句能够很好地实现条件代码,但是它们不是没有缺点。 它们主要适用于您只有几个选择的情况,每个都需要相当数量的代码来运行,和/或 的条件很复杂的情况(例如多个逻辑运算符)。 对于只想将变量设置一系列为特定值的选项或根据条件打印特定语句的情况,语法可能会很麻烦,特别是如果您有大量选择。
switch
语句在这里是您的朋友 - 他们以单个表达式/值作为输入,然后查看多个选项,直到找到与该值相匹配的选项,执行与之相关的代码。 这里有一些伪代码,可以给你一点灵感:
switch (expression) { case choice1: run this code break; case choice2: run this code instead break; // include as many cases as you like default: actually, just run this code }
这里我们得到:
switch
, 后跟一组括号.case
, 后跟一个选项的表达式/值,后面跟一个冒号.break
语句, 分号结尾. 如果先前的选择与表达式/值匹配,则浏览器在此停止执行代码块,并执行switch语句之后的代码.default
, 后面跟随和 case
完全相同的代码模式 (选项 3–5), except that default
之后不需要再有选项, 并且您不需要 break
语句, 因为之后没有任何运行代码. 如果之前没有选项匹配,则运行default
选项.Note: default
部分不是必须的 - 如果表达式不可能存在未知值,则可以安全地省略它。 如果有机会,您需要包括它来处理未知的情况。
我们来看一个真实的例子 - 我们将重写天气预报应用程序,以改用switch语句:
<label for="weather">Select the weather type today: </label> <select id="weather"> <option value="">--Make a choice--</option> <option value="sunny">Sunny</option> <option value="rainy">Rainy</option> <option value="snowing">Snowing</option> <option value="overcast">Overcast</option> </select> <p></p>
var select = document.querySelector('select'); var para = document.querySelector('p'); select.addEventListener('change', setWeather); function setWeather() { var choice = select.value; switch (choice) { case 'sunny': para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.'; break; case 'rainy': para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.'; break; case 'snowing': para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.'; break; case 'overcast': para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.'; break; default: para.textContent = ''; } }
{{ EmbedLiveSample('A_switch_example', '100%', 100) }}
Note: 你可以 在 GitHub 上找到这个例子 (也可以在线运行。)
在我们举一些例子之前,我们要介绍一下最后一句语法。三元或条件运算符是一个语法的小点,用于测试一个条件,并返回一个值/表达,如果它是true
,另一个是false
-这种情况下是有用的,并且可以占用比if...else
块较少的代码块。如果你只有两个通过true
/ false
条件选择。伪代码看起来像这样:
( condition ) ? run this code : run this code instead
所以我们来看一个简单的例子:
var greeting = ( isBirthday ) ? 'Happy birthday Mrs. Smith — we hope you have a great day!' : 'Good morning Mrs. Smith.';
在这里我们有一个变量叫做isBirthday
- 如果它是true
,我们给客人一个生日快乐的消息; 如果不是,我们给她标准的每日问候。
你不需要用三元运算符设置变量值; 你也可以运行任何你喜欢的函数或代码行。以下实例显示了一个简单的主题选择器,其中该站点的样式应用了三元运算符。
<label for="theme">Select theme: </label> <select id="theme"> <option value="white">White</option> <option value="black">Black</option> </select> <h1>This is my website</h1>
var select = document.querySelector('select'); var html = document.querySelector('html'); document.body.style.padding = '10px'; function update(bgColor, textColor) { html.style.backgroundColor = bgColor; html.style.color = textColor; } select.onchange = function() { ( select.value === 'black' ) ? update('black','white') : update('white','black'); }
{{ EmbedLiveSample('Ternary_operator_example', '100%', 300) }}
在这里,我们有一个<select>
选择主题(黑色或白色)的元素,加上一个简单<h1>
的显示网站标题。我们也有一个函数叫做update()
,它将两种颜色作为参数(输入)。网站的背景颜色设置为第一个提供的颜色,其文本颜色设置为第二个提供的颜色。
最后,我们还有一个onchange事件监听器,用于运行一个包含三元运算符的函数。它以测试条件开始select.value === 'black'
。如果这返回true
,我们运行update()
带有黑色和白色参数的函数,这意味着我们最终得到黑色的背景颜色和白色的文字颜色。如果返回false
,我们运行update()
带有白色和黑色参数的函数,这意味着站点颜色被反转。
Note: 你可以 在 GitHub 上找到这个例子 (也可以在线运行。)
在这个例子中,您将帮助我们完成一个简单的日历应用程序。在你的代码中:
<select>
元素,允许用户在不同月份之间进行选择。onchange
检测<select>
菜单中选择的值何时更改的事件处理程序。createCalendar()
绘制日历并在<h1>
元素中显示正确的月份。我们需要你在onchange
处理函数中写一个条件语句,就在// ADD CONDITIONAL HERE
任务的下面 。这应该:
choice
变量中,这将是<select>
值更改后的元素值,例如“1月”)。days
为等于所选月份天数的变量。为此,您必须查看一年中每个月的天数。为了这个例子的目的,你可以忽略闰年。提示:
如果您犯了错误,您可以随时使用“Reset”按钮重置该示例。如果真的卡住了,请按“Show solution”查看解决方案。
<div class="output" style="height: 500px;overflow: auto;"> <label for="month">Select month: </label> <select id="month"> <option value="January">January</option> <option value="February">February</option> <option value="March">March</option> <option value="April">April</option> <option value="May">May</option> <option value="June">June</option> <option value="July">July</option> <option value="August">August</option> <option value="September">September</option> <option value="October">October</option> <option value="November">November</option> <option value="December">December</option> </select> <h1></h1> <ul></ul> </div> <hr> <textarea id="code" class="playable-code" style="height: 500px;"> var select = document.querySelector('select'); var list = document.querySelector('ul'); var h1 = document.querySelector('h1'); select.onchange = function() { var choice = select.value; // ADD CONDITIONAL HERE createCalendar(days, choice); } function createCalendar(days, choice) { list.innerHTML = ''; h1.textContent = choice; for (var i = 1; i <= days; i++) { var listItem = document.createElement('li'); listItem.textContent = i; list.appendChild(listItem); } } createCalendar(31,'January'); </textarea> <div class="playable-buttons"> <input id="reset" type="button" value="Reset"> <input id="solution" type="button" value="Show solution"> </div>
.output * { box-sizing: border-box; } .output ul { padding-left: 0; } .output li { display: block; float: left; width: 25%; border: 2px solid white; padding: 5px; height: 40px; background-color: #4A2DB6; color: white; }
var textarea = document.getElementById('code'); var reset = document.getElementById('reset'); var solution = document.getElementById('solution'); var code = textarea.value; function updateCode() { eval(textarea.value); } reset.addEventListener('click', function() { textarea.value = code; updateCode(); }); solution.addEventListener('click', function() { textarea.value = jsSolution; updateCode(); }); var jsSolution = 'var select = document.querySelector(\'select\');\nvar list = document.querySelector(\'ul\');\nvar h1 = document.querySelector(\'h1\');\n\nselect.onchange = function() {\n var choice = select.value;\n var days = 31;\n if(choice === \'February\') {\n days = 28;\n } else if(choice === \'April\' || choice === \'June\' || choice === \'September\'|| choice === \'November\') {\n days = 30;\n }\n\n createCalendar(days, choice);\n}\n\nfunction createCalendar(days, choice) {\n list.innerHTML = \'\';\n h1.textContent = choice;\n for(var i = 1; i <= days; i++) {\n var listItem = document.createElement(\'li\');\n listItem.textContent = i;\n list.appendChild(listItem);\n }\n }\n\ncreateCalendar(31,\'January\');'; textarea.addEventListener('input', updateCode); window.addEventListener('load', updateCode);
{{ EmbedLiveSample('Playable_code', '100%', 1110) }}
在这个例子中,您将要采取我们前面看到的三元运算符示例,并将三元运算符转换为一个switch语句,这将允许我们对简单的网站应用更多的选择。看看<select>
- 这次你会看到它不是两个主题选项,而是五个。您需要在// ADD SWITCH STATEMENT
注释下面添加一个switch语句:
choice
变量作为其输入表达式。update()
函数,并传递两个颜色值,第一个颜色值为背景颜色,第二个颜色值为文本颜色。请记住,颜色值是字符串,因此需要用引号括起来。如果您犯了错误,您可以随时使用“Reset”按钮重置该示例。如果真的卡住了,请按“Show solution”查看解决方案。
<div class="output" style="height: 300px;"> <label for="theme">Select theme: </label> <select id="theme"> <option value="white">White</option> <option value="black">Black</option> <option value="purple">Purple</option> <option value="yellow">Yellow</option> <option value="psychedelic">Psychedelic</option> </select> <h1>This is my website</h1> </div> <hr> <textarea id="code" class="playable-code" style="height: 450px;"> var select = document.querySelector('select'); var html = document.querySelector('.output'); select.onchange = function() { var choice = select.value; // ADD SWITCH STATEMENT } function update(bgColor, textColor) { html.style.backgroundColor = bgColor; html.style.color = textColor; }</textarea> <div class="playable-buttons"> <input id="reset" type="button" value="Reset"> <input id="solution" type="button" value="Show solution"> </div>
var textarea = document.getElementById('code'); var reset = document.getElementById('reset'); var solution = document.getElementById('solution'); var code = textarea.value; function updateCode() { eval(textarea.value); } reset.addEventListener('click', function() { textarea.value = code; updateCode(); }); solution.addEventListener('click', function() { textarea.value = jsSolution; updateCode(); }); var jsSolution = 'var select = document.querySelector(\'select\');\nvar html = document.querySelector(\'.output\');\n\nselect.onchange = function() {\n var choice = select.value;\n\n switch(choice) {\n case \'black\':\n update(\'black\',\'white\');\n break;\n case \'white\':\n update(\'white\',\'black\');\n break;\n case \'purple\':\n update(\'purple\',\'white\');\n break;\n case \'yellow\':\n update(\'yellow\',\'darkgray\');\n break;\n case \'psychedelic\':\n update(\'lime\',\'purple\');\n break;\n }\n}\n\nfunction update(bgColor, textColor) {\n html.style.backgroundColor = bgColor;\n html.style.color = textColor;\n}'; textarea.addEventListener('input', updateCode); window.addEventListener('load', updateCode);
{{ EmbedLiveSample('Playable_code_2', '100%', 850) }}
这就是现在您真正需要了解的JavaScript中的条件结构!我相信你会理解这些概念,并轻松地通过这些例子; 如果有什么不明白的,请随时阅读文章,或者联系我们寻求帮助。
{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}