笔记参考javascript.info中文站
条件分支:if 和 ‘?’
1. if 语句
if(...)
语句计算括号里的条件表达式,如果计算结果是 true
,就会执行对应的代码块。
let year = prompt('In which year was ECMAScript-2015 specification published?', '');
if (year == 2015) alert( 'You are right!' );
if(...)
括号里的条件表达式是一个布尔变量,如果不是,那就把它转换成布尔变量,目的是判断是否执行 if 语句。
具体转换参照布尔类型转换章节的内容
2. else 和 else if
当有多种情况需要判断时,需要用到 else 或 else if 语句
else 代表除此以外的所有情况,因此没有判断条件
let year = prompt('In which year was ECMAScript-2015 specification published?', '');
if (year == 2015) {
alert( 'You guessed it right!' );
} else {
alert( 'How can you be so wrong?' ); // 2015 以外的任何值
}
有时判断情况多于两个,需要用到else if,个数不限,顺序是从上往下依次判断
let year = prompt('In which year was ECMAScript-2015 specification published?', '');
if (year < 2015) {
alert( 'Too early' );
} else if (year > 2015) {
alert( 'Too late' );
} else {
alert( 'Exactly!' );
}
3. 条件转移符 “?”
“?” 是一个三元运算符,很适合根据一个条件去赋值一个变量的情况,计算 condition 结果,如果结果为真,则返回 value1,否则返回 value2。
let result = condition ? value1 : value2;
举个例子:
let accessAllowed = (age > 18) ? true : false; // 大于十八岁则允许进入,否则禁止进入
除此之外,条件转移符也是按照顺序执行的,因此可能出现多个 “?” 同时存在的情况,相比 if 语句简介,但可读性差,个人并不推荐
举个例子:
let age = prompt('age?', 18);
// 条件转移符写法,很模糊
let message = (age < 3) ? 'Hi, baby!' :
(age < 18) ? 'Hello!' :
(age < 100) ? 'Greetings!' :
'What an unusual age!';
alert( message );
// if 语句写法,很直观
if (age < 3) {
message = 'Hi, baby!';
} else if (age < 18) {
message = 'Hello!';
} else if (age < 100) {
message = 'Greetings!';
} else {
message = 'What an unusual age!';
}
alert( message );
事实上,“?” 不仅可以赋值布尔变量,也可以直接运行命令,举个例子
let company = prompt('Which company created JavaScript?', '');
(company == 'Netscape') ?
alert('Right!') : alert('Wrong.');
// 相比于 if 语句更加简洁
逻辑运算符
虽然被称为 “逻辑运算符” ,但事实上它们不止作用于布尔变量,可以作用于任意类型变量
1. ||(或运算)
布尔变量的运算往往用于在 if 语句中,用来测试是否有任何给定的条件为 true
let hour = 9;
if (hour < 10 || hour > 18) {
alert( 'The office is closed.' );
}
或运算还有一个特性,按顺序运算,有真值则返回第一个真值,不存在真值则返回最后一个值。
alert( null || 0 || 1 ); // 1(第一个真值)
alert( undefined || null || 0 ); // 0(都是假值,返回最后一个值)
我们可以利用这个特性做两件事
1. 获取 变量列表 或 表达式 中的第一个真值
let firstName = "";
let lastName = "";
let nickName = "SuperCoder";
alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
如果前三个都为假,那么返回 “Anonymous”
2. 短路求值
当或运算遇到第一个真值时会立即停止运算,不看后面的表达式或变量,我们可以利用这个性质做出类似 if 语句的效果,即只在左侧的条件为假时才执行命令。
true || alert("not printed"); // true 为真,不运行后面的alert
false || alert("printed"); // false 为假,继续往后看,触发alert
2. &&(与运算)
布尔运算同样主要用于 if 语句判断
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'Time is 12:30' );
}
与运算同样按照顺序运算,一旦碰到 false 则停止运算,没有遇到则返回最后一个操作数(真值)
alert( 1 && 2 && null && 3 ); // null
alert( 1 && 2 && 3 ); // 3,最后一个值
注意,与运算 && 的优先级比或运算 || 要高,举个例子:
a && b || c && d
等价于 (a && b) || (c && d)
3. !(非运算)
! 运算表示取反,且在所有逻辑运算符里面优先级最高,总在 && 和 || 之前执行。
alert( !true ); // false
alert( !!"non-empty string" ); // true,双重取反,可用于任意值到布尔值的转化
4. ??(空值合并运算符)
一个最近新增到 Javascript 的特性
a ?? b
的结果是:
- 如果 a 是已定义的,则结果为 a
- 如果 a 不是已定义的,则结果为 b
否则你就要这样写
result = (a !== null && a !== undefined) ? a : b;
举个应用的例子:
// 有名字用名字,没名字用“匿名”
let user;
alert(user ?? "匿名"); // 匿名(user 未定义)
user = "John";
alert(user ?? "匿名"); // John(user 已定义)
?? 运算同样是顺序进行,因此我们还可以使用 ?? 从一系列的值中选择出第一个非 null/undefined 的值(注意与 || 的区别,或运算选出的是第一个真值)
优先级与或运算相同
循环:while 和 for
1. “while” 循环
当 condition 为真时,执行循环体的 code。
while (condition) {
// “循环体”
}
一般随着迭代次数增加,循环体会改变某个变量的值,使得条件不成立,从而停止循环。
let i = 3;
while (i) { // 当 i 变成 0 时,条件为假,循环终止
alert( i );
i--;
}
2. “do…while” 循环
与 while 循环类似,只不过先执行循环体,再判断一次,也就是至少执行一次循环体,不常用
do {
// 循环体
} while (condition);
3. “for” 循环
更加复杂,但 for 是最常使用的循环形式。
for (begin; condition; step) {
// ……循环体……
}
部分 | 说明 |
---|---|
begin | 初次进入 for 循环时执行一次,确定 |
condition | 在每次循环迭代之前检查,如果为 false,停止循环 |
step | 在每次循环体迭代后执行,方便跳出循环 |
举个例子:
for (let i = 0; i < 3; i++) { // 结果为 0、1、2
alert(i);
}
alert(i); // 错误,i是内联变量,循环外其实没有这个变量
// 但我们也可以直接使用已经声明过的变量作为begin,这样就可以在循环外调用了
let i = 0;
for (i = 0; i < 3; i++) { // 使用现有的变量
alert(i); // 0, 1, 2
}
alert(i); //3,可见,因为是在循环之外声明的
for 循环的三个部分也可以省略,但这会降低可读性,如:
let i = 0; // 我们已经声明了 i 并对它进行了赋值
for (; i < 3; i++) { // 不再需要 "begin" 语句段
alert( i ); // 0, 1, 2
}
// 甚至可以全省略
for (;;) {
// 无限循环
}
4. break 和 continue
break
指令
break
可以让我们随时跳出某一层循环,常用于 “满足某个条件时停止循环” 这个需求,以停止死循环。
let sum = 0;
while (true) {
let value = +prompt("Enter a number", '');
if (!value) break; // 如果用户停止输入,则停止循环
sum += value;
}
alert( 'Sum: ' + sum );
continue
指令
continue
可以让我们随时跳出某一次循环,仅限于单次,常用于 “跳过某些不被需要的内容” 这一需求。
for (let i = 0; i < 10; i++) {
//如果为真,跳过循环体的剩余部分,也就是跳过偶数
if (i % 2 == 0) continue;
alert(i); // 1,然后 3,5,7,9
}
注意,break/continue 指令并不是表达式指令,禁止用在 “?” 后面
- break/continue 标签
有时候我们需要一次从多层嵌套的循环中跳出来,而break
只能跳出一层,于是标签诞生了
标签 是在循环之前带有冒号的标识符:
labelName: for (...) {
...
}
break 语句跳出循环至标签处:
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`Value at coords (${i},${j})`, '');
// 如果是空字符串或被取消,则中断并跳出这两个循环。
if (!input) break outer; // 直接break到标签的outer层
// 用得到的值做些事……
}
}
alert('Done!');
continue 同理