if 语句
语法:
if (condition) {
statement1
} else {
statement2
}
condition:表达式,求值结果会被转换为布尔值,为true执行语句 statement1,为false执行语句 statement2。- 可连续使用多个
if语句。
if (i > 25) {
console.log("Greater than 25.");
} else if (i < 0) {
console.log("Less than 0.");
} else {
console.log("Between 0 and 25, inclusive.");
}
最佳实践是使用语句块,即使只有一行代码要执行也是如此。这是因为语句块可以避免对什么条件下执行什么产生困惑。
while 语句
while 语句是一种先测试循环语句,即先检测退出条件,再执行循环体内的代码。因此,while 循环体内的代码有可能不会执行。
语法:
while(expression) {
statement
}
condition:表达式,求值结果会被转换为布尔值,为true执行语句 statement。
例子:
let i = 0;
while (i < 10) {
i += 2;
}
在这个例子中,变量 i 从 0 开始,每次循环递增 2。只要 i 小于 10,循环就会继续。
无限循环:while (true) {...} 。
do...while 语句
do...while 语句是一种后测试循环语句,即先执行循环体中的代码后,才会对退出条件进行求值。换句话说,循环体内的代码至少执行一次。
语法:
do {
statement
} while (expression);
例子:
let i = 0;
do {
i += 2;
} while (i < 10);
在这个例子中,只要 i 小于 10,循环就会重复执行。i 从 0 开始,每次循环递增 2。
for 语句
for 语句也是先测试语句,只不过增加了进入循环之前的初始化代码,以及循环执行后要执行的表达式。
语法:
for (initialization; expression; postLoopExpression){
statement
}
initialization:初始化代码expression:退出条件求值表达式postLoopExpression:循环执行后要执行的表达式
let count = 10;
for (let i = 0; i < count; i++) {
console.log(i);
}
在 for 循环的初始化代码中,其实是可以不使用变量声明关键字的。不过,初始化定义的迭代器变量在循环执行完成后几乎不可能再用到了。因此,最清晰的写法是使用 let 声明迭代器变量,这样就可以将这个变量的作用域限定在循环中。
初始化、条件表达式和循环后表达式都不是必需的。因此,下面这种写法可以创建一个无穷循环:
for (;;) { // 无穷循环
doSomething();
}
请注意
for的两个;必须存在,否则会出现语法错误。
for...in 语句
for...in 语句是一种 严格的迭代语句,用于枚举对象中的 非符号键 属性。
语法:
for (property in expression) statement
property:局部变量,用于保存键名expression:对象(对象为null或undefined,则不执行循环体)
for (const propName in window) {
document.write(propName);
}
这个例子使用 for...in 循环显示了 BOM 对象 window 的所有属性。每次执行循环,都会给变量 propName 赋予一个 window 对象的属性作为值,直到 window 的所有属性都被枚举一遍。
与 for 循环一样,这里控制语句中的 const 也不是必需的。但为了确保这个局部变量不被修改,推荐使用 const。
ECMAScript 中对象的属性是无序的,因此 for...in 语句不能保证返回对象属性的顺序。换句话说,所有可枚举的属性都会返回一次,但返回的顺序可能会因浏览器而异。
for...of 语句
for...of 语句是一种 严格的迭代语句,用于遍历 可迭代对象 的元素。
语法:
for (property of expression) statement
for (const el of [2,4,6,8]) {
document.write(el);
}
与 for 循环一样,这里控制语句中的 const 也不是必需的。
for...of 循环会按照可迭代对象的 next() 方法产生值的顺序迭代元素。
如果尝试迭代的变量不支持迭代,则 for...of 语句会抛出错误。
标签语句
标签语句用于给语句加标签。
语法:
label: statement
start: for (let i = 0; i < count; i++) {
console.log(i);
}
在这个例子中,start 是一个标签,可以在后面通过 break 或 continue 语句引用。标签语句的典型应用场景是嵌套循环。标签是 break/continue 调出嵌套循环以转到外部的唯一方法。
标签并不允许我们调到代码的任意位置。 只有在循环内部才能调用
break或continue,并且标签必须位于指令上方的某个位置。
break label; // 无法跳转到这个标签
label: for (...)
break 和 continue 语句
break:结束当前循环;continue:跳过当前循环,执行下一次的循环;
// break
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
break;
}
num++;
}
console.log(num); // 4。当 i 等于 5 时,break 语句会导致循环退出,num 不递增
// continue
let num = 0;
for (let i = 1; i < 10; i++) {
if (i % 5 == 0) {
continue;
}
num++;
}
console.log(num); // 8。num 的值是 8 而不是 9,是因为 continue 语句导致它少递增了一次
break 和 continue 都可以与标签语句一起使用,返回代码中特定的位置。这通常是在嵌套循环中,如下面的例子所示:
let num = 0;
outermost:
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
console.log(num); // 55
在这个例子中,outermost 标签标识的是第一个 for 语句。正常情况下,每个循环执行 10 次,意味着 num++ 语句会执行 100 次,而循环结束时 console.log 的结果应该是 100。但是,break 语句带来了一个变数,即要退出到的标签。添加标签不仅让 break 退出(使用变量 j 的)内部循环,也会退出(使用变量 i 的)外部循环。当执行到 i 和 j 都等于 5 时,循环停止执行,此时 num 的值是 55。
continue 语句也可以使用标签,如下面的例子所示:
let num = 0;
outermost:
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
continue outermost;
}
num++;
}
}
console.log(num); // 95
这一次,continue 语句会强制循环继续执行,但不是继续执行内部循环,而是继续执行外部循环。当 i 和 j 都等于 5 时,会执行 continue,跳到外部循环继续执行,从而导致内部循环少执行 5 次,结果 num 等于 95。
组合使用标签语句和 break、continue 能实现复杂的逻辑,但也容易出错。注意标签要使用描述性强的文本,而嵌套也不要太深。
with 语句
with 语句的用途是将代码作用域设置为特定的对象。
语法:
with (expression) statement;
使用 with 语句的主要场景是针对一个对象反复操作,这时候将代码作用域设置为该对象能提供便
利,如下面的例子所示:
let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;
上面代码中的每一行都用到了 location 对象。如果使用 with 语句,就可以少写一些代码:
with(location) {
let qs = search.substring(1);
let hostName = hostname;
let url = href;
}
这里,with 语句用于连接 location 对象。这意味着在这个语句内部,每个变量首先会被认为是一个局部变量。如果没有找到该局部变量,则会搜索 location 对象,看它是否有一个同名的属性。如果有,则该变量会被求值为 location 对象的属性。
严格模式不允许使用 with 语句,否则会抛出错误。
由于
with语句影响性能且难于调试其中的代码,通常不推荐在产品代码中使用with语句。
switch 语句
switch 语句是与 if 语句紧密相关的一种流控制语句,从其他语言借鉴而来。
switch (expression) {
case value1:
statement
break;
case value2:
statement
break;
default:
statement
}
expression:表达式case(条件/分支):如果表达式等于后面的值,则执行下面的 statement 语句。break关键字会导致代码执行跳出switch语句。如果没有break,则代码会继续匹配下一个条件。default关键字用于在任何条件都没有满足时指定默认执行的语句(相当于else语句)。
为避免不必要的条件判断,最好给每个条件后面都加上 break 语句。如果确实需要连续匹配几个条件,那么推荐写个注释表明是故意忽略了 break,如下所示:
switch (i) {
case 25:
/* 跳过 */
case 35:
console.log("25 or 35");
break;
case 45:
console.log("45");
break;
default:
console.log("Other");
}
虽然 switch 语句是从其他语言借鉴过来的,但 ECMAScript 为它赋予了一些独有的特性:
switch语句可以用于所有数据类型,因此可以使用字符串甚至对象。- 条件的值不需要是常量,也可以是变量或表达式。
- 任何表达式都可以成为
switch/case的参数。
let num = 25;
switch (true) {
case num < 0:
console.log("Less than 0.");
break;
case num >= 0 && num <= 10:
console.log("Between 0 and 10.");
break;
case num > 10 && num <= 20:
console.log("Between 10 and 20.");
break;
default:
console.log("More than 20.");
}
上面的代码首先在外部定义了变量 num,而传给 switch 语句的参数之所以是 true,就是因为每个条件的表达式都会返回布尔值。条件的表达式分别被求值,直到有表达式返回 true;否则,就会一直跳到 default 语句。
注意:switch 语句在比较每个条件的值时会使用 全等操作符 ,因此不会强制转换数据类型(比如,字符串"10"不等于数值 10)。
return 语句
- 返回函数的值
- 函数停止执行并退出
function sum(num1, num2) {
return num1 + num2;
console.log('该代码不会被执行'); // return 语句后面的代码不会被执行
}
const result = sum(5, 10);
最佳实践是函数要么返回值,要么不返回值。只在某个条件下返回值的函数会带来麻烦,尤其是调试时。